1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-02 20:35:25 +02:00

feat(OAuth): Add SSO support for OAuth EE-390 (#5087)

* add updateSettingsToDB28 func and test

* update DBversion const

* migration func naming modification

* feat(oauth): add sso, hide internal auth teaser and logout options. (#5039)

* cleanup and make helper func for unit testing

* dbversion update

* feat(publicSettings): public settings response modification for OAuth SSO EE-608 (#5062)

* feat(oauth): updated logout logic with logoutUrl. (#5064)

* add exclusive token generation for OAuth

* swagger annotation revision

* add unit test

* updates based on tech review feedback

* feat(oauth): updated oauth settings model

* feat(oauth): added oauth logout url

* feat(oauth): fixed SSO toggle and logout issue.

* set SSO to ON by default

* update migrator unit test

* set SSO to true by default for new instance

* prevent applying the SSO logout url to the initial admin user

Co-authored-by: fhanportainer <79428273+fhanportainer@users.noreply.github.com>
Co-authored-by: Felix Han <felix.han@portainer.io>
This commit is contained in:
Hui 2021-06-11 10:09:04 +12:00 committed by GitHub
parent 14ac005627
commit f674573cdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 412 additions and 84 deletions

View file

@ -18,6 +18,7 @@ export function PublicSettingsViewModel(settings) {
this.LogoURL = settings.LogoURL;
this.OAuthLoginURI = settings.OAuthLoginURI;
this.EnableTelemetry = settings.EnableTelemetry;
this.OAuthLogoutURI = settings.OAuthLogoutURI;
}
export function LDAPSettingsViewModel(data) {
@ -52,4 +53,6 @@ export function OAuthSettingsViewModel(data) {
this.Scopes = data.Scopes;
this.OAuthAutoCreateUsers = data.OAuthAutoCreateUsers;
this.DefaultTeamID = data.DefaultTeamID;
this.SSO = data.SSO;
this.LogoutURI = data.LogoutURI;
}

View file

@ -1,4 +1,32 @@
<div>
<div
><div class="col-sm-12 form-section-title">
Single Sign-On
</div>
<!-- SSO -->
<div class="form-group">
<label for="use-sso" class="control-label col-sm-2 text-left" style="padding-top: 0;">
Use SSO
<portainer-tooltip position="bottom" message="When using SSO the OAuth provider is not forced to prompt for credentials."></portainer-tooltip>
</label>
<div class="col-sm-9">
<label class="switch"> <input id="use-sso" type="checkbox" ng-model="$ctrl.settings.SSO" /><i></i> </label>
</div>
</div>
<!-- !SSO -->
<!-- HideInternalAuth -->
<div class="form-group" ng-if="$ctrl.settings.SSO">
<label for="hide-internal-auth" class="control-label col-sm-2 text-left" style="padding-top: 0;">
Hide internal authentication prompt
</label>
<div class="col-sm-9">
<label class="switch"> <input id="hide-internal-auth" type="checkbox" disabled /><i></i> </label>
<span class="text-muted small" style="margin-left: 15px;">
This feature is available in <a href="https://www.portainer.io/business-upsell?from=hide-internal-auth" target="_blank"> Portainer Business Edition</a>.
</span>
</div>
</div>
<!-- !HideInternalAuth -->
<div class="col-sm-12 form-section-title">
Automatic user provisioning
</div>
@ -105,7 +133,18 @@
<input type="text" class="form-control" id="oauth_redirect_uri" ng-model="$ctrl.settings.RedirectURI" placeholder="http://yourportainer.com/" />
</div>
</div>
<div class="form-group">
<label for="oauth_logout_url" class="col-sm-3 col-lg-2 control-label text-left">
Logout URL
<portainer-tooltip
position="bottom"
message="URL used by Portainer to redirect the user to the OAuth provider in order to log the user out of the identity provider session."
></portainer-tooltip>
</label>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="oauth_logout_url" ng-model="$ctrl.settings.LogoutURI" />
</div>
</div>
<div class="form-group">
<label for="oauth_user_identifier" class="col-sm-3 col-lg-2 control-label text-left">
User identifier

View file

@ -2,15 +2,17 @@ import angular from 'angular';
class LogoutController {
/* @ngInject */
constructor($async, $state, $transition$, Authentication, StateManager, Notifications, LocalStorage) {
constructor($async, $state, $transition$, $window, Authentication, StateManager, Notifications, LocalStorage, SettingsService) {
this.$async = $async;
this.$state = $state;
this.$transition$ = $transition$;
this.$window = $window;
this.Authentication = Authentication;
this.StateManager = StateManager;
this.Notifications = Notifications;
this.LocalStorage = LocalStorage;
this.SettingsService = SettingsService;
this.logo = this.StateManager.getState().application.logo;
this.logoutAsync = this.logoutAsync.bind(this);
@ -24,11 +26,17 @@ class LogoutController {
async logoutAsync() {
const error = this.$transition$.params().error;
const performApiLogout = this.$transition$.params().performApiLogout;
const settings = await this.SettingsService.publicSettings();
try {
await this.Authentication.logout(performApiLogout);
} finally {
this.LocalStorage.storeLogoutReason(error);
this.$state.go('portainer.auth', { reload: true });
if (settings.OAuthLogoutURI && this.Authentication.getUserDetails().ID !== 1) {
this.$window.location.href = settings.OAuthLogoutURI;
} else {
this.$state.go('portainer.auth', { reload: true });
}
}
}