Skip to content

Commit 7ecf7e9

Browse files
committed
Conflicts: zeppelin-server/src/main/java/org/apache/zeppelin/server/CorsFilter.java zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTests.java
2 parents faa6204 + 47902a6 commit 7ecf7e9

File tree

11 files changed

+850
-26
lines changed

11 files changed

+850
-26
lines changed

zeppelin-server/src/main/java/org/apache/zeppelin/server/CorsFilter.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,14 @@
1717

1818
package org.apache.zeppelin.server;
1919

20+
import org.apache.zeppelin.conf.ZeppelinConfiguration;
21+
import org.apache.zeppelin.utils.SecurityUtils;
22+
2023
import java.io.IOException;
2124
import java.net.URI;
25+
import java.net.URISyntaxException;
2226
import java.text.DateFormat;
27+
import java.util.Arrays;
2328
import java.util.Date;
2429
import java.util.Locale;
2530

@@ -41,11 +46,15 @@ public class CorsFilter implements Filter {
4146
@Override
4247
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
4348
throws IOException, ServletException {
44-
String sourceHost = request.getServerName();
45-
String currentHost = java.net.InetAddress.getLocalHost().getHostName();
49+
String sourceHost = ((HttpServletRequest) request).getHeader("Origin");
4650
String origin = "";
47-
if (currentHost.equals(sourceHost) || "localhost".equals(sourceHost)) {
48-
origin = ((HttpServletRequest) request).getHeader("Origin");
51+
52+
try {
53+
if (SecurityUtils.isValidOrigin(sourceHost, ZeppelinConfiguration.create())) {
54+
origin = sourceHost;
55+
}
56+
} catch (URISyntaxException e) {
57+
e.printStackTrace();
4958
}
5059

5160
if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {

zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.apache.zeppelin.scheduler.JobListener;
4242
import org.apache.zeppelin.server.ZeppelinServer;
4343
import org.apache.zeppelin.socket.Message.OP;
44+
import org.apache.zeppelin.utils.SecurityUtils;
4445
import org.eclipse.jetty.websocket.WebSocket;
4546
import org.eclipse.jetty.websocket.WebSocketServlet;
4647
import org.quartz.SchedulerException;
@@ -66,24 +67,15 @@ private Notebook notebook() {
6667
}
6768
@Override
6869
public boolean checkOrigin(HttpServletRequest request, String origin) {
69-
URI sourceUri = null;
70-
String currentHost = null;
7170

7271
try {
73-
sourceUri = new URI(origin);
74-
currentHost = java.net.InetAddress.getLocalHost().getHostName();
72+
return SecurityUtils.isValidOrigin(origin, ZeppelinConfiguration.create());
7573
} catch (UnknownHostException e) {
7674
e.printStackTrace();
77-
}
78-
catch (URISyntaxException e) {
75+
} catch (URISyntaxException e) {
7976
e.printStackTrace();
8077
}
8178

82-
String sourceHost = sourceUri.getHost();
83-
if (currentHost.equals(sourceHost) || "localhost".equals(sourceHost)) {
84-
return true;
85-
}
86-
8779
return false;
8880
}
8981

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.zeppelin.utils;
18+
19+
import org.apache.zeppelin.conf.ZeppelinConfiguration;
20+
21+
import java.net.URI;
22+
import java.net.URISyntaxException;
23+
import java.net.UnknownHostException;
24+
25+
/**
26+
* Created by joelz on 8/19/15.
27+
*/
28+
public class SecurityUtils {
29+
public static Boolean isValidOrigin(String sourceHost, ZeppelinConfiguration conf)
30+
throws UnknownHostException, URISyntaxException {
31+
URI sourceHostUri = new URI(sourceHost.toLowerCase());
32+
String currentHost = java.net.InetAddress.getLocalHost().getHostName().toLowerCase();
33+
if (currentHost.equals(sourceHostUri.getHost()) ||
34+
"localhost".equals(sourceHostUri.getHost()) ||
35+
conf.getAllowedOrigins().contains(sourceHost)) {
36+
return true;
37+
}
38+
39+
return false;
40+
}
41+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.zeppelin.security;
18+
19+
import junit.framework.Assert;
20+
import org.apache.commons.configuration.ConfigurationException;
21+
import org.apache.zeppelin.conf.ZeppelinConfiguration;
22+
import org.apache.zeppelin.utils.SecurityUtils;
23+
import org.junit.Test;
24+
25+
import java.net.URISyntaxException;
26+
import java.net.UnknownHostException;
27+
28+
/**
29+
* Created by joelz on 8/19/15.
30+
*/
31+
public class SecurityUtilsTests {
32+
@Test
33+
public void isLocalhost() throws URISyntaxException, UnknownHostException {
34+
Assert.assertTrue(SecurityUtils.isValidOrigin("http://localhost", ZeppelinConfiguration.create()));
35+
}
36+
37+
@Test
38+
public void isLocalMachine() throws URISyntaxException, UnknownHostException {
39+
Assert.assertTrue(SecurityUtils.isValidOrigin(
40+
"http://" + java.net.InetAddress.getLocalHost().getHostName(),
41+
ZeppelinConfiguration.create()));
42+
}
43+
44+
@Test
45+
public void isValidFromConfig() throws URISyntaxException, UnknownHostException, ConfigurationException {
46+
Assert.assertTrue(
47+
SecurityUtils.isValidOrigin("http://otherhost.com",
48+
new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site.xml"))));
49+
}
50+
}

zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTests.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,8 @@
1919
*/
2020
package org.apache.zeppelin.socket;
2121

22-
import org.apache.zeppelin.notebook.Note;
23-
import org.apache.zeppelin.server.ZeppelinServer;
2422
import org.junit.Assert;
25-
import org.junit.FixMethodOrder;
2623
import org.junit.Test;
27-
import org.junit.runners.MethodSorters;
2824

2925
import java.io.IOException;
3026
import org.junit.Assert;
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<?xml version="1.0"?>
2+
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
3+
<!--
4+
Licensed to the Apache Software Foundation (ASF) under one or more
5+
contributor license agreements. See the NOTICE file distributed with
6+
this work for additional information regarding copyright ownership.
7+
The ASF licenses this file to You under the Apache License, Version 2.0
8+
(the "License"); you may not use this file except in compliance with
9+
the License. You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
-->
19+
20+
<configuration>
21+
22+
<property>
23+
<name>zeppelin.server.addr</name>
24+
<value>0.0.0.0</value>
25+
<description>Server address</description>
26+
</property>
27+
28+
<property>
29+
<name>zeppelin.server.port</name>
30+
<value>8080</value>
31+
<description>Server port.</description>
32+
</property>
33+
34+
<property>
35+
<name>zeppelin.notebook.dir</name>
36+
<value>notebook</value>
37+
<description>path or URI for notebook persist</description>
38+
</property>
39+
40+
<property>
41+
<name>zeppelin.notebook.homescreen</name>
42+
<value></value>
43+
<description>id of notebook to be displayed in homescreen. ex) 2A94M5J1Z Empty value displays default home screen</description>
44+
</property>
45+
46+
<property>
47+
<name>zeppelin.notebook.homescreen.hide</name>
48+
<value>false</value>
49+
<description>hide homescreen notebook from list when this value set to true</description>
50+
</property>
51+
52+
53+
<!-- If used S3 to storage the notebooks, it is necessary the following folder structure bucketname/username/notebook/ -->
54+
<!--
55+
<property>
56+
<name>zeppelin.notebook.s3.user</name>
57+
<value>user</value>
58+
<description>user name for s3 folder structure</description>
59+
</property>
60+
61+
<property>
62+
<name>zeppelin.notebook.s3.bucket</name>
63+
<value>zeppelin</value>
64+
<description>bucket name for notebook storage</description>
65+
</property>
66+
67+
<property>
68+
<name>zeppelin.notebook.storage</name>
69+
<value>org.apache.zeppelin.notebook.repo.S3NotebookRepo</value>
70+
<description>notebook persistence layer implementation</description>
71+
</property>
72+
-->
73+
74+
<property>
75+
<name>zeppelin.notebook.storage</name>
76+
<value>org.apache.zeppelin.notebook.repo.VFSNotebookRepo</value>
77+
<description>notebook persistence layer implementation</description>
78+
</property>
79+
80+
<property>
81+
<name>zeppelin.interpreter.dir</name>
82+
<value>interpreter</value>
83+
<description>Interpreter implementation base directory</description>
84+
</property>
85+
86+
<property>
87+
<name>zeppelin.interpreters</name>
88+
<value>org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.postgresql.PostgreSqlInterpreter</value>
89+
<description>Comma separated interpreter configurations. First interpreter become a default</description>
90+
</property>
91+
92+
<property>
93+
<name>zeppelin.interpreter.connect.timeout</name>
94+
<value>30000</value>
95+
<description>Interpreter process connect timeout in msec.</description>
96+
</property>
97+
98+
99+
<property>
100+
<name>zeppelin.ssl</name>
101+
<value>false</value>
102+
<description>Should SSL be used by the servers?</description>
103+
</property>
104+
105+
<property>
106+
<name>zeppelin.ssl.client.auth</name>
107+
<value>false</value>
108+
<description>Should client authentication be used for SSL connections?</description>
109+
</property>
110+
111+
<property>
112+
<name>zeppelin.ssl.keystore.path</name>
113+
<value>keystore</value>
114+
<description>Path to keystore relative to Zeppelin configuration directory</description>
115+
</property>
116+
117+
<property>
118+
<name>zeppelin.ssl.keystore.type</name>
119+
<value>JKS</value>
120+
<description>The format of the given keystore (e.g. JKS or PKCS12)</description>
121+
</property>
122+
123+
<property>
124+
<name>zeppelin.ssl.keystore.password</name>
125+
<value>change me</value>
126+
<description>Keystore password. Can be obfuscated by the Jetty Password tool</description>
127+
</property>
128+
129+
<!--
130+
<property>
131+
<name>zeppelin.ssl.key.manager.password</name>
132+
<value>change me</value>
133+
<description>Key Manager password. Defaults to keystore password. Can be obfuscated.</description>
134+
</property>
135+
-->
136+
137+
<property>
138+
<name>zeppelin.ssl.truststore.path</name>
139+
<value>truststore</value>
140+
<description>Path to truststore relative to Zeppelin configuration directory. Defaults to the keystore path</description>
141+
</property>
142+
143+
<property>
144+
<name>zeppelin.ssl.truststore.type</name>
145+
<value>JKS</value>
146+
<description>The format of the given truststore (e.g. JKS or PKCS12). Defaults to the same type as the keystore type</description>
147+
</property>
148+
149+
<property>
150+
<name>zeppelin.server.allowed.origins</name>
151+
<value>http://onehost:8080,http://otherhost.com,</value>
152+
<description>Allowed sources for REST and WebSocket requests.</description>
153+
</property>
154+
<!--
155+
<property>
156+
<name>zeppelin.ssl.truststore.password</name>
157+
<value>change me</value>
158+
<description>Truststore password. Can be obfuscated by the Jetty Password tool. Defaults to the keystore password</description>
159+
</property>
160+
-->
161+
162+
</configuration>
163+

0 commit comments

Comments
 (0)