You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ja...@apache.org on 2018/10/09 09:09:24 UTC
[20/27] lucene-solr:solr7896-login-page: New iteration. Intercepts
WWW-authenticate header and allows separate screens per type WORK IN PROGRESS
New iteration. Intercepts WWW-authenticate header and allows separate screens per type
WORK IN PROGRESS
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/9012e40a
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/9012e40a
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/9012e40a
Branch: refs/heads/solr7896-login-page
Commit: 9012e40a5c2afd8bd8f482ea208d255da1af6e76
Parents: 9ee3506
Author: Jan Høydahl <ja...@apache.org>
Authored: Fri Oct 5 16:41:25 2018 +0200
Committer: Jan Høydahl <ja...@apache.org>
Committed: Fri Oct 5 16:41:25 2018 +0200
----------------------------------------------------------------------
.../apache/solr/security/BasicAuthPlugin.java | 6 +
solr/webapp/web/index.html | 5 +-
solr/webapp/web/js/angular/app.js | 117 +++++++++++--------
solr/webapp/web/js/angular/controllers/login.js | 38 ++++--
solr/webapp/web/js/angular/services.js | 22 +++-
solr/webapp/web/partials/login.html | 33 +++++-
6 files changed, 151 insertions(+), 70 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9012e40a/solr/core/src/java/org/apache/solr/security/BasicAuthPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/security/BasicAuthPlugin.java b/solr/core/src/java/org/apache/solr/security/BasicAuthPlugin.java
index 3533b9e..597df7c 100644
--- a/solr/core/src/java/org/apache/solr/security/BasicAuthPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/BasicAuthPlugin.java
@@ -108,6 +108,12 @@ public class BasicAuthPlugin extends AuthenticationPlugin implements ConfigEdita
}
response.setHeader(entry.getKey(), value);
}
+ // NOCOMMIT - which headers to set?
+ // Need to explicitly allow Admin UI to read these headers from the 401 response
+// response.setHeader("Access-Control-Expose-Headers", "WWW-Authenticate, X-Solr-AuthData");
+// response.setHeader("Access-Control-Allow-Origin", "*");
+// response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
+// response.setHeader("Access-Control-Max-Age", "3600");
response.sendError(401, message);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9012e40a/solr/webapp/web/index.html
----------------------------------------------------------------------
diff --git a/solr/webapp/web/index.html b/solr/webapp/web/index.html
index d832155..4b83533 100644
--- a/solr/webapp/web/index.html
+++ b/solr/webapp/web/index.html
@@ -64,9 +64,6 @@ limitations under the License.
<script src="libs/jquery-ui.min.js"></script>
<script src="js/angular/app.js"></script>
<script src="js/angular/services.js"></script>
- <script src="js/angular/directives.js"></script>
- <script src="js/angular/http-auth-interceptor.js"></script>
- <script src="js/angular/login-controllers.js"></script>
<script src="js/angular/controllers/index.js"></script>
<script src="js/angular/controllers/login.js"></script>
<script src="js/angular/controllers/logging.js"></script>
@@ -144,7 +141,7 @@ limitations under the License.
<div>
<ul id="menu">
- <li id="login" class="global" ng-class="{active:page=='login'}"><p><a href="#/login">Logout</a></p></li>
+ <li id="login" class="global" ng-class="{active:page=='login'}"><p><a href="#/login">Logout {{username}}</a></p></li>
<li id="index" class="global" ng-class="{active:page=='index'}"><p><a href="#/">Dashboard</a></p></li>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9012e40a/solr/webapp/web/js/angular/app.js
----------------------------------------------------------------------
diff --git a/solr/webapp/web/js/angular/app.js b/solr/webapp/web/js/angular/app.js
index 71dd98b..36dd07c 100644
--- a/solr/webapp/web/js/angular/app.js
+++ b/solr/webapp/web/js/angular/app.js
@@ -369,66 +369,85 @@ solrAdminApp.config([
$rootScope.exceptions[rejection.config.url] = rejection.data.error;
}
return $q.reject(rejection);
- }
+ };
return {request: started, response: ended, responseError: failed};
})
// NOCOMMIT First iteration
-// .factory('authInterceptor', function($q, $rootScope, $timeout, $injector) {
-// var started = function(config) {
-// var ah = "Basic c29scjpyb2Nrcw=="; // solr / SolrRocks
-// config.headers['Authorization'] = ah;
-// console.log("Added authorization header " + ah);
-// return config || $q.when(config);
-// };
-//
-// var ended = function(response) {
-// console.log("Response headers: " + JSON.stringify(response.headers, undefined, 2));
-// if (response.headers['WWW-Authenticate'] != null) {
-// console.log("Got WWW-Authenticate header: " + response.headers['WWW-Authenticate']);
-// }
-// return response || $q.when(response);
-// };
-//
-// var failed = function(rejection) {
-// console.log("Failed with rejection " + JSON.stringify(rejection, undefined, 2));
-// if (rejection.status === 401) {
-// console.log("Status code is 401");
-// } else {
-// console.log("Rejection status is " + rejection.status)
-// }
-// $rootScope.$broadcast('loadingStatusInactive');
-// return $q.reject(rejection);
-// };
-//
-// return {request: started, response: ended, responseError: failed};
-// })
+.factory('authInterceptor', function($q, $rootScope, $location, $timeout, $injector) {
+ var started = function(config) {
+ console.log("Request config: " + JSON.stringify(config, undefined, 2));
+ // var ah = "Basic c29scjpyb2Nrcw=="; // solr / SolrRocks
+ // config.headers['Authorization'] = ah;
+ // console.log("Added authorization header " + ah);
+ if (sessionStorage.getItem("auth.header") !== null) {
+ if (config.headers['Authorization'] === null) {
+ config.headers['Authorization'] = sessionStorage.getItem("auth.header");
+ console.log("We have a logged in user with header " + sessionStorage.getItem("auth.username") + ", appending header");
+ }
+ }
+ return config || $q.when(config);
+ };
+
+ var ended = function(response) {
+ console.log("Response headers: " + JSON.stringify(response.headers(), undefined, 2));
+ return response || $q.when(response);
+ };
+
+ var failed = function(rejection) {
+ console.log("Failed with rejection " + JSON.stringify(rejection, undefined, 2));
+ if (rejection.status === 401) {
+ console.log("Status code is 401");
+ var headers = rejection.headers();
+ console.log("Headers are " + JSON.stringify(headers, undefined, 2));
+ var wwwAuthHeader = headers['www-authenticate'];
+ sessionStorage.setItem("auth.wwwAuthHeader", wwwAuthHeader);
+ var authDataHeader = headers['X-Solr-AuthData'];
+ if (authDataHeader !== null) {
+ sessionStorage.setItem("auth.config", authDataHeader);
+ }
+ console.log("Got WWW-Authenticate header: " + wwwAuthHeader + " and X-Solr-AuthData: " + authDataHeader);
+ var authType = wwwAuthHeader.split(" ")[0];
+ console.log("AuthType is: " + authType);
+ sessionStorage.setItem("auth.type", authType);
+ sessionStorage.setItem("auth.location", $location.path());
+ sessionStorage.removeItem("auth.username");
+ sessionStorage.removeItem("auth.header");
+ $location.path('/login');
+ } else {
+ console.log("Rejection status is " + rejection.status)
+ }
+ $rootScope.$broadcast('loadingStatusInactive');
+ return $q.reject(rejection);
+ };
+
+ return {request: started, response: ended, responseError: failed};
+})
.config(function($httpProvider) {
$httpProvider.interceptors.push("httpInterceptor");
- // NOCOMMIT $httpProvider.interceptors.push("authInterceptor");
- // Tell the BasicAuth plugin that we are Admin UI so it can serve us a 'Authorization: xBasic xxxx' header
- // so that the browser will not interfer with the login dialogue
+ $httpProvider.interceptors.push("authInterceptor");
+ // Force BasicAuth plugin to serve us a 'Authorization: xBasic xxxx' header so browser will not pop up login dialogue
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
})
// NOCOMMIT: just for testing
-.run(['$rootScope', '$location', '$cookieStore', '$http',
- function ($rootScope, $location, $cookieStore, $http) {
- // keep user logged in after page refresh
- // Replace with interceptor
- $rootScope.globals = $cookieStore.get('globals') || {};
- if ($rootScope.globals.currentUser) {
- $http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata; // jshint ignore:line
- }
-
- $rootScope.$on('$locationChangeStart', function (event, next, current) {
- // redirect to login page if not logged in
- if ($location.path() !== '/login' && !$rootScope.globals.currentUser) {
- $location.path('/login');
- }
- });
- }])
+// .run(['$rootScope', '$location', '$cookieStore', '$http',
+// function ($rootScope, $location, $cookieStore, $http) {
+// // keep user logged in after page refresh
+// // Replace with interceptor
+// $rootScope.globals = $cookieStore.get('globals') || {};
+// if ($rootScope.globals.currentUser) {
+// $http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata; // jshint ignore:line
+// }
+//
+// // $rootScope.$on('$locationChangeStart', function (event, next, current) {
+// // // redirect to login page if not logged in
+// // if ($location.path() !== '/login' && !$rootScope.globals.currentUser) {
+// // $location.path('/login');
+// // }
+// // });
+// }])
.directive('fileModel', function ($parse) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9012e40a/solr/webapp/web/js/angular/controllers/login.js
----------------------------------------------------------------------
diff --git a/solr/webapp/web/js/angular/controllers/login.js b/solr/webapp/web/js/angular/controllers/login.js
index 653ca14..a67119c8 100644
--- a/solr/webapp/web/js/angular/controllers/login.js
+++ b/solr/webapp/web/js/angular/controllers/login.js
@@ -16,15 +16,28 @@
*/
solrAdminApp.controller('LoginController',
- ['$scope', '$rootScope', '$location', 'AuthenticationService',
- function ($scope, $rootScope, $location, AuthenticationService) {
- // reset login status
- AuthenticationService.ClearCredentials();
-
+ ['$scope', '$routeParams', '$rootScope', '$location', 'AuthenticationService',
+ function ($scope, $routeParams, $rootScope, $location, AuthenticationService) {
+ var authType = sessionStorage.getItem("auth.type");
+ var basicTypes = ['Basic', 'xBasic'];
+ if (authType !== null && basicTypes.includes(authType)) {
+ if (authType === 'xBasic') authType = 'Basic';
+ $scope.authType = authType;
+ } else {
+ $scope.authType = 'unknown';
+ }
+
+ $scope.wwwAuthHeader = sessionStorage.getItem("auth.wwwAuthHeader");
+ $scope.authConfig = sessionStorage.getItem("auth.config");
+ $scope.authLocation = sessionStorage.getItem("auth.location");
+ $scope.authLoggedinUser = sessionStorage.getItem("auth.username");
+ $scope.authHeader = sessionStorage.getItem("auth.header");
+
$scope.login = function () {
- $scope.dataLoading = true;
AuthenticationService.SetCredentials($scope.username, $scope.password);
- $location.path('/');
+ console.log("Redirecting back to " + $scope.authLocation);
+ $location.path($scope.authLocation); // Redirect to the location that caused the login prompt
+
// TODO: "login" by hitting the failing URL again
// AuthenticationService.Login($scope.username, $scope.password, function (response) {
// if (response.success) {
@@ -36,4 +49,15 @@ solrAdminApp.controller('LoginController',
// }
// });
};
+
+ $scope.logout = function() {
+ // reset login status
+ AuthenticationService.ClearCredentials();
+ console.log("Logged out user and cleared creds");
+ $location.path("/");
+ };
+
+ $scope.isLoggedIn = function() {
+ return (sessionStorage.getItem("auth.username") !== null);
+ };
}]);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9012e40a/solr/webapp/web/js/angular/services.js
----------------------------------------------------------------------
diff --git a/solr/webapp/web/js/angular/services.js b/solr/webapp/web/js/angular/services.js
index b6df864..323bc8e 100644
--- a/solr/webapp/web/js/angular/services.js
+++ b/solr/webapp/web/js/angular/services.js
@@ -264,8 +264,8 @@ solrAdminServices.factory('System',
})
}])
.factory('AuthenticationService',
- ['Base64', '$http', '$cookieStore', '$rootScope', '$timeout',
- function (Base64, $http, $cookieStore, $rootScope, $timeout) {
+ ['Base64', '$http', '$rootScope', '$timeout',
+ function (Base64, $http, $rootScope, $timeout) {
var service = {};
service.Login = function (username, password, callback) {
@@ -293,6 +293,9 @@ solrAdminServices.factory('System',
service.SetCredentials = function (username, password) {
var authdata = Base64.encode(username + ':' + password);
+ sessionStorage.setItem("auth.username", username);
+ $rootScope.username = username;
+
$rootScope.globals = {
currentUser: {
username: username,
@@ -300,14 +303,21 @@ solrAdminServices.factory('System',
}
};
- $http.defaults.headers.common['Authorization'] = 'Basic ' + authdata; // jshint ignore:line
- $cookieStore.put('globals', $rootScope.globals);
+ // $http.defaults.headers.common['Authorization'] = 'Basic ' + authdata; // jshint ignore:line
+ $http.defaults.headers.common.Authorization = 'Basic ' + authdata;
+ // sessionStorage.setItem('globals', $rootScope.globals);
+ sessionStorage.setItem("auth.header", authdata);
+ console.log("Stored auth data on session storage");
};
service.ClearCredentials = function () {
$rootScope.globals = {};
- $cookieStore.remove('globals');
- $http.defaults.headers.common.Authorization = 'Basic ';
+ // sessionStorage.removeItem('globals');
+ sessionStorage.removeItem("auth.header");
+ sessionStorage.removeItem("auth.username");
+ sessionStorage.removeItem("auth.wwwAuthHeader");
+ $http.defaults.headers.common.Authorization = null;
+ console.log("Cleared stored auth data");
};
return service;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9012e40a/solr/webapp/web/partials/login.html
----------------------------------------------------------------------
diff --git a/solr/webapp/web/partials/login.html b/solr/webapp/web/partials/login.html
index 65be563..37768cf 100644
--- a/solr/webapp/web/partials/login.html
+++ b/solr/webapp/web/partials/login.html
@@ -15,12 +15,18 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<div id="login">
- <div class="col-xs-offset-2 col-xs-8">
- <h1>Please log in</h1>
- Basic Authentication
+
+ <div class="col-xs-offset-2 col-xs-8" ng-show="authType === 'Basic'">
+ <h1>Basic Authentication</h1>
+ <p>Type: {{authType}}</p>
+ <p>WWW-Header: {{wwwAuthHeader}}</p>
+ <p>Config: {{authConfig}}</p>
+ <p>Redirect: {{authLocation}}</p>
+ <p>LoggedinUser: {{authLoggedinUser}}</p>
+
<div ng-show="error" class="alert alert-danger">{{error}}</div>
- <form name="form" ng-submit="login()" role="form">
+ <form name="form" ng-submit="login()" role="form" ng-show="!isLoggedIn()">
<div class="form-group">
<label for="username">Username</label>
<i class="fa fa-key"></i>
@@ -38,5 +44,24 @@ limitations under the License.
<img ng-if="dataLoading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />
</div>
</form>
+ <form name="logoutForm" ng-submit="logout()" role="form" ng-show="isLoggedIn()">
+ <div class="form-actions">
+ <button type="submit" class="btn btn-danger">Logout</button>
+ </div>
+ </form>
+
+ </div>
+
+
+ <div class="col-xs-offset-2 col-xs-8" ng-show="authType === 'unknown'">
+ <h1>Authentication type not supported</h1>
+
+ <p>Type: {{authType}}</p>
+ <p>WWW-Header: {{wwwAuthHeader}}</p>
+ <p>Config: {{authConfig}}</p>
+ <p>Redirect: {{authLocation}}</p>
+ <p>LoggedinUser: {{authLoggedinUser}}</p>
+
+ You cannot use Solr's Admin UI for this operation. Please use another client that supports this type.
</div>
</div>