fix(oauth): okta support (#3051)

* fix(oauth): okta support

* fix(oauth): state to follow OAuth 2 RFC against CSRF
pull/3086/head
xAt0mZ 2019-08-12 16:26:06 +02:00 committed by GitHub
commit 552c897b3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 5 deletions

View File

@ -14,6 +14,12 @@ angular.module('portainer.app')
getEndpointPublicURL: function() {
return localStorageService.get('ENDPOINT_PUBLIC_URL');
},
storeLoginStateUUID: function(uuid) {
localStorageService.set('LOGIN_STATE_UUID', uuid);
},
getLoginStateUUID: function() {
return localStorageService.get('LOGIN_STATE_UUID');
},
storeOfflineMode: function(isOffline) {
localStorageService.set('ENDPOINT_OFFLINE_MODE', isOffline);
},

View File

@ -1,6 +1,8 @@
import uuidv4 from 'uuid/v4';
angular.module('portainer.app')
.controller('AuthenticationController', ['$async', '$q', '$scope', '$state', '$stateParams', '$sanitize', 'Authentication', 'UserService', 'EndpointService', 'ExtensionService', 'StateManager', 'Notifications', 'SettingsService', 'URLHelper',
function($async, $q, $scope, $state, $stateParams, $sanitize, Authentication, UserService, EndpointService, ExtensionService, StateManager, Notifications, SettingsService, URLHelper) {
.controller('AuthenticationController', ['$async', '$q', '$scope', '$state', '$stateParams', '$sanitize', 'Authentication', 'UserService', 'EndpointService', 'ExtensionService', 'StateManager', 'Notifications', 'SettingsService', 'URLHelper', 'LocalStorage',
function($async, $q, $scope, $state, $stateParams, $sanitize, Authentication, UserService, EndpointService, ExtensionService, StateManager, Notifications, SettingsService, URLHelper, LocalStorage) {
$scope.logo = StateManager.getState().application.logo;
$scope.formValues = {
@ -116,12 +118,23 @@ function($async, $q, $scope, $state, $stateParams, $sanitize, Authentication, Us
return 'OAuth';
}
function generateState() {
const uuid = uuidv4();
LocalStorage.storeLoginStateUUID(uuid);
return '&state=' + uuid;
}
function hasValidState(state) {
const savedUUID = LocalStorage.getLoginStateUUID();
return savedUUID === state;
}
function initView() {
SettingsService.publicSettings()
.then(function success(settings) {
$scope.AuthenticationMethod = settings.AuthenticationMethod;
$scope.OAuthLoginURI = settings.OAuthLoginURI;
$scope.state.OAuthProvider = determineOauthProvider(settings.OAuthLoginURI);
$scope.OAuthLoginURI = settings.OAuthLoginURI + generateState();
});
if ($stateParams.logout || $stateParams.error) {
@ -142,8 +155,9 @@ function($async, $q, $scope, $state, $stateParams, $sanitize, Authentication, Us
authenticatedFlow();
}
var code = URLHelper.getParameter('code');
if (code) {
const code = URLHelper.getParameter('code');
const state = URLHelper.getParameter('state');
if (code && hasValidState(state)) {
oAuthLogin(code);
} else {
$scope.state.isInOAuthProcess = false;