You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by pr...@apache.org on 2018/08/22 08:40:06 UTC
zeppelin git commit: [ZEPPELIN-3741] Do not clear "Authorization"
header if Z-server is running behind proxy
Repository: zeppelin
Updated Branches:
refs/heads/master e10332c93 -> 3047bc2f5
[ZEPPELIN-3741] Do not clear "Authorization" header if Z-server is running behind proxy
There can be a case where Zeppelin-Sever is running as Form-Based-Authentication, however, it can be running behind a proxy which may be requiring Authorization header.
The idea of this PR is to not clear that header when it behind a proxy and control it with config.
[Bug Fix]
* [x] - Add documentaion
* [ZEPPELIN-3741](https://issues.apache.org/jira/browse/ZEPPELIN-3741)
* Configure Nginx to run with `auth_basic` option
* Start Zeppelin server behind a proxy server like Nginx
* Make sure that `shiro.ini` is configured to run with `/** = authc`
* In `zeppelin-site.xml` configure `zeppelin.server.authorization.header.clear` as `false`
Now on logout from Zeppelin-Server should not clear *Authorization* header of Nginx
* Does the licenses files need update? N/A
* Is there breaking changes for older versions? N/A
* Does this needs documentation? Yes
Author: Prabhjyot Singh <pr...@gmail.com>
Closes #3155 from prabhjyotsingh/ZEPPELIN-3741 and squashes the following commits:
d95fc32dc [Prabhjyot Singh] add documentation
54daaca8d [Prabhjyot Singh] rename variable to "zeppelin.server.authorization.header.clear"
832ef0481 [Prabhjyot Singh] ZEPPELIN-3741: Do not clear "Authorization" header if Z-server is running behind proxy
Change-Id: I8c504e170b576570dbb888160946a2c477d7928e
Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/3047bc2f
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/3047bc2f
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/3047bc2f
Branch: refs/heads/master
Commit: 3047bc2f595415560276832a8ca7ac178adff677
Parents: e10332c
Author: Prabhjyot Singh <pr...@gmail.com>
Authored: Tue Aug 21 18:57:19 2018 +0530
Committer: Prabhjyot Singh <pr...@gmail.com>
Committed: Wed Aug 22 14:09:57 2018 +0530
----------------------------------------------------------------------
conf/zeppelin-site.xml.template | 8 +++
docs/setup/security/shiro_authentication.md | 6 ++
.../zeppelin/conf/ZeppelinConfiguration.java | 5 ++
.../org/apache/zeppelin/rest/LoginRestApi.java | 24 +++++--
.../src/components/navbar/navbar.controller.js | 74 +++++++++++---------
5 files changed, 79 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/3047bc2f/conf/zeppelin-site.xml.template
----------------------------------------------------------------------
diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template
index 31f8f73..9d9a99f 100755
--- a/conf/zeppelin-site.xml.template
+++ b/conf/zeppelin-site.xml.template
@@ -486,6 +486,14 @@
<!--
<property>
+ <name>zeppelin.server.authorization.header.clear</name>
+ <value>true</value>
+ <description>Authorization header to be cleared if server is running as authcBasic</description>
+</property>
+-->
+
+<!--
+<property>
<name>zeppelin.server.xframe.options</name>
<value>SAMEORIGIN</value>
<description>The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a frame/iframe/object.</description>
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/3047bc2f/docs/setup/security/shiro_authentication.md
----------------------------------------------------------------------
diff --git a/docs/setup/security/shiro_authentication.md b/docs/setup/security/shiro_authentication.md
index 11d5c68..bb655f1 100644
--- a/docs/setup/security/shiro_authentication.md
+++ b/docs/setup/security/shiro_authentication.md
@@ -307,6 +307,12 @@ anyofrolesuser = org.apache.zeppelin.utils.AnyOfRolesUserAuthorizationFilter
> **NOTE :** All of the above configurations are defined in the `conf/shiro.ini` file.
+## FAQ
+
+Zeppelin sever is configured as form-based authentication but is behind proxy configured as basic-authentication for example [NGINX](./authentication_nginx.html#http-basic-authentication-using-nginx) and don't want Zeppelin-Server to clear authentication headers.
+
+> Set `zeppelin.server.authorization.header.clear` to `false` in zeppelin-site.xml
+
## Other authentication methods
- [HTTP Basic Authentication using NGINX](./authentication_nginx.html)
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/3047bc2f/zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
index df74283..2b2f3b6 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
@@ -571,6 +571,10 @@ public class ZeppelinConfiguration extends XMLConfiguration {
return getInt(ConfVars.ZEPPELIN_SERVER_JETTY_REQUEST_HEADER_SIZE);
}
+ public Boolean isAuthorizationHeaderClear() {
+ return getBoolean(ConfVars.ZEPPELIN_SERVER_AUTHORIZATION_HEADER_CLEAR);
+ }
+
public String getXFrameOptions() {
return getString(ConfVars.ZEPPELIN_SERVER_XFRAME_OPTIONS);
@@ -759,6 +763,7 @@ public class ZeppelinConfiguration extends XMLConfiguration {
ZEPPELIN_SERVER_XFRAME_OPTIONS("zeppelin.server.xframe.options", "SAMEORIGIN"),
ZEPPELIN_SERVER_JETTY_NAME("zeppelin.server.jetty.name", null),
ZEPPELIN_SERVER_JETTY_REQUEST_HEADER_SIZE("zeppelin.server.jetty.request.header.size", 8192),
+ ZEPPELIN_SERVER_AUTHORIZATION_HEADER_CLEAR("zeppelin.server.authorization.header.clear", true),
ZEPPELIN_SERVER_STRICT_TRANSPORT("zeppelin.server.strict.transport", "max-age=631138519"),
ZEPPELIN_SERVER_X_XSS_PROTECTION("zeppelin.server.xxss.protection", "1"),
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/3047bc2f/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java
index 2937d02..f13c222 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/LoginRestApi.java
@@ -17,6 +17,7 @@
package org.apache.zeppelin.rest;
import com.google.gson.Gson;
+import javax.inject.Inject;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
@@ -25,6 +26,8 @@ import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.Subject;
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.notebook.Notebook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -62,6 +65,12 @@ import org.apache.zeppelin.utils.SecurityUtils;
public class LoginRestApi {
private static final Logger LOG = LoggerFactory.getLogger(LoginRestApi.class);
private static final Gson gson = new Gson();
+ private ZeppelinConfiguration zConf;
+
+ @Inject
+ public LoginRestApi(Notebook notebook) {
+ this.zConf = notebook.getConf();
+ }
@GET
@ZeppelinApi
@@ -205,15 +214,22 @@ public class LoginRestApi {
public Response logout() {
JsonResponse response;
logoutCurrentUser();
+ Status status = null;
+ Map<String, String> data = new HashMap<>();
+ if (zConf.isAuthorizationHeaderClear()) {
+ status = Status.UNAUTHORIZED;
+ data.put("clearAuthorizationHeader", "true");
+ } else {
+ status = Status.FORBIDDEN;
+ data.put("clearAuthorizationHeader", "false");
+ }
if (isKnoxSSOEnabled()) {
KnoxJwtRealm knoxJwtRealm = getJTWRealm();
- Map<String, String> data = new HashMap<>();
data.put("redirectURL", constructKnoxUrl(knoxJwtRealm, knoxJwtRealm.getLogout()));
data.put("isLogoutAPI", knoxJwtRealm.getLogoutAPI().toString());
- response = new JsonResponse(Status.UNAUTHORIZED, "", data);
+ response = new JsonResponse(status, "", data);
} else {
- response = new JsonResponse(Status.UNAUTHORIZED, "", "");
-
+ response = new JsonResponse(status, "", data);
}
LOG.warn(response.toString());
return response.build();
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/3047bc2f/zeppelin-web/src/components/navbar/navbar.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/navbar/navbar.controller.js b/zeppelin-web/src/components/navbar/navbar.controller.js
index 7665bf8..68a7f4a 100644
--- a/zeppelin-web/src/components/navbar/navbar.controller.js
+++ b/zeppelin-web/src/components/navbar/navbar.controller.js
@@ -91,6 +91,7 @@ function NavCtrl($scope, $rootScope, $http, $routeParams, $location,
let logoutURL = baseUrlSrv.getRestApiBase() + '/login/logout';
$http.post(logoutURL).then(function() {}, function(response) {
+ let clearAuthorizationHeader = 'true';
if (response.data) {
let res = angular.fromJson(response.data).body;
if (res['redirectURL']) {
@@ -104,44 +105,49 @@ function NavCtrl($scope, $rootScope, $http, $routeParams, $location,
}
return undefined;
}
+ if (res['clearAuthorizationHeader']) {
+ clearAuthorizationHeader = res['clearAuthorizationHeader'];
+ }
}
// force authcBasic (if configured) to logout
- if (detectIE()) {
- let outcome;
- try {
- outcome = document.execCommand('ClearAuthenticationCache');
- } catch (e) {
- console.log(e);
- }
- if (!outcome) {
- // Let's create an xmlhttp object
- outcome = (function(x) {
- if (x) {
- // the reason we use "random" value for password is
- // that browsers cache requests. changing
- // password effectively behaves like cache-busing.
- x.open('HEAD', location.href, true, 'logout',
- (new Date()).getTime().toString());
- x.send('');
- // x.abort()
- return 1; // this is **speculative** "We are done."
- } else {
- // eslint-disable-next-line no-useless-return
- return;
- }
- })(window.XMLHttpRequest ? new window.XMLHttpRequest()
- // eslint-disable-next-line no-undef
- : (window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : u));
- }
- if (!outcome) {
- let m = 'Your browser is too old or too weird to support log out functionality. Close all windows and ' +
- 'restart the browser.';
- alert(m);
+ if (clearAuthorizationHeader === 'true') {
+ if (detectIE()) {
+ let outcome;
+ try {
+ outcome = document.execCommand('ClearAuthenticationCache');
+ } catch (e) {
+ console.log(e);
+ }
+ if (!outcome) {
+ // Let's create an xmlhttp object
+ outcome = (function(x) {
+ if (x) {
+ // the reason we use "random" value for password is
+ // that browsers cache requests. changing
+ // password effectively behaves like cache-busing.
+ x.open('HEAD', location.href, true, 'logout',
+ (new Date()).getTime().toString());
+ x.send('');
+ // x.abort()
+ return 1; // this is **speculative** "We are done."
+ } else {
+ // eslint-disable-next-line no-useless-return
+ return;
+ }
+ })(window.XMLHttpRequest ? new window.XMLHttpRequest()
+ // eslint-disable-next-line no-undef
+ : (window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : u));
+ }
+ if (!outcome) {
+ let m = 'Your browser is too old or too weird to support log out functionality. Close all windows and ' +
+ 'restart the browser.';
+ alert(m);
+ }
+ } else {
+ // for firefox and safari
+ logoutURL = logoutURL.replace('//', '//false:false@');
}
- } else {
- // for firefox and safari
- logoutURL = logoutURL.replace('//', '//false:false@');
}
$http.post(logoutURL).error(function() {