oidc now working
This commit is contained in:
@@ -14,6 +14,7 @@ import LocalStorage from 'app/features/global/framework/local-storage-service';
|
|||||||
|
|
||||||
const OIDC_CALLBACK_URL = '/oidccallback';
|
const OIDC_CALLBACK_URL = '/oidccallback';
|
||||||
const OIDC_SIGNOUT_URL = '/signout';
|
const OIDC_SIGNOUT_URL = '/signout';
|
||||||
|
const OIDC_SILENT_URL = '/oidcsilent';
|
||||||
|
|
||||||
@TwakeService('OIDCAuthProvider')
|
@TwakeService('OIDCAuthProvider')
|
||||||
export default class OIDCAuthProviderService
|
export default class OIDCAuthProviderService
|
||||||
@@ -50,13 +51,15 @@ export default class OIDCAuthProviderService
|
|||||||
client_id: this.configuration?.client_id,
|
client_id: this.configuration?.client_id,
|
||||||
redirect_uri: getAsFrontUrl(OIDC_CALLBACK_URL),
|
redirect_uri: getAsFrontUrl(OIDC_CALLBACK_URL),
|
||||||
response_type: 'code',
|
response_type: 'code',
|
||||||
|
response_mode: 'query',
|
||||||
scope: 'openid profile email address phone offline_access',
|
scope: 'openid profile email address phone offline_access',
|
||||||
post_logout_redirect_uri: getAsFrontUrl(OIDC_SIGNOUT_URL),
|
post_logout_redirect_uri: getAsFrontUrl(OIDC_SIGNOUT_URL),
|
||||||
//silent_redirect_uri: getAsFrontUrl(OIDC_SILENT_URL),
|
silent_redirect_uri: getAsFrontUrl(OIDC_SILENT_URL),
|
||||||
automaticSilentRenew: true,
|
automaticSilentRenew: true,
|
||||||
loadUserInfo: true,
|
loadUserInfo: true,
|
||||||
accessTokenExpiringNotificationTime: 60,
|
accessTokenExpiringNotificationTime: 10,
|
||||||
filterProtocolClaims: true,
|
filterProtocolClaims: true,
|
||||||
|
monitorSession: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// For logout if signout or logout endpoint called
|
// For logout if signout or logout endpoint called
|
||||||
@@ -66,129 +69,59 @@ export default class OIDCAuthProviderService
|
|||||||
this.signOut();
|
this.signOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.userManager.events.addUserLoaded(user => {
|
this.userManager.events.addUserLoaded((user: any) => {
|
||||||
// fires each time the user is loaded or updated
|
console.log('New User Loaded:', arguments);
|
||||||
this.logger.debug('OIDC user loaded listener', user);
|
console.log('Acess_token: ', user.access_token);
|
||||||
this.user = user;
|
});
|
||||||
|
|
||||||
this.getJWTFromOidcToken(user, (err, jwt) => {
|
this.userManager.events.addAccessTokenExpiring(function () {
|
||||||
if (err) {
|
console.log('AccessToken Expiring:', arguments);
|
||||||
this.logger.error(
|
|
||||||
'OIDC user loaded listener, error while getting the JWT from OIDC token',
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
this.signinRedirect();
|
|
||||||
// FIXME: Should we return?
|
|
||||||
//return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.initialized) {
|
|
||||||
// FIXME: Do we need to send back the user?
|
|
||||||
this.onInitialized();
|
|
||||||
this.initialized = true;
|
|
||||||
} else {
|
|
||||||
jwt && params.onNewToken(jwt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.userManager.events.addAccessTokenExpired(() => {
|
this.userManager.events.addAccessTokenExpired(() => {
|
||||||
this.logger.debug('OIDC access token expired listener');
|
console.log('AccessToken Expired:', arguments);
|
||||||
this.silentLogin();
|
|
||||||
// FIXME: use params.onSessionExpired() if we can not renew
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.userManager.events.addAccessTokenExpiring(() => {
|
this.userManager.events.addSilentRenewError(function () {
|
||||||
this.logger.debug('OIDC access token is expiring');
|
console.error('Silent Renew Error:', arguments);
|
||||||
this.silentLogin();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.userManager.events.addSilentRenewError(error => {
|
(async () => {
|
||||||
// in case the renew failed, ask for login
|
try {
|
||||||
// since we have set automaticSilentRenew to true, this will be called when silentSignin raise error when token is expiring
|
await this.userManager!.signinRedirectCallback();
|
||||||
this.logger.error('OIDC silent renew error', error);
|
} catch (e) {}
|
||||||
this.signOut();
|
|
||||||
});
|
|
||||||
|
|
||||||
//This even listener is temporary disabled because of this issue: https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/-/issues/2358
|
const user = await this.userManager?.getUser();
|
||||||
this.userManager.events.addUserSignedOut(() => {
|
|
||||||
this.logger.info('OIDC Signed out listener');
|
|
||||||
//this.signOut();
|
|
||||||
});
|
|
||||||
|
|
||||||
//This manage the initial sign-in when loading the app
|
if (user) {
|
||||||
if (this.enforceFrontendUrl()) {
|
this.getJWTFromOidcToken(user, (err, jwt) => {
|
||||||
this.silentLogin();
|
if (err) {
|
||||||
}
|
this.logger.error(
|
||||||
|
'OIDC user loaded listener, error while getting the JWT from OIDC token',
|
||||||
|
err,
|
||||||
|
);
|
||||||
|
this.signinRedirect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.initialized) {
|
||||||
|
this.onInitialized();
|
||||||
|
this.initialized = true;
|
||||||
|
} else {
|
||||||
|
jwt && params.onNewToken(jwt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.userManager?.signinRedirect();
|
||||||
|
}
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Redirect to valid frontend url to make sure oidc will work as expected
|
|
||||||
private enforceFrontendUrl() {
|
|
||||||
const frontUrl = (getDomain(environment.front_root_url || '') || '').toLocaleLowerCase();
|
|
||||||
|
|
||||||
if (frontUrl && document.location.host.toLocaleLowerCase() !== frontUrl) {
|
|
||||||
document.location.replace(
|
|
||||||
document.location.protocol +
|
|
||||||
'//' +
|
|
||||||
getDomain(environment.front_root_url) +
|
|
||||||
'/' +
|
|
||||||
document.location.pathname +
|
|
||||||
document.location.search +
|
|
||||||
document.location.hash,
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async silentLogin(): Promise<void> {
|
|
||||||
if (!this.userManager) {
|
|
||||||
this.logger.debug('silentLogin, no auth provider');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Try to use the in-url sign-in response from oidc if exists
|
|
||||||
try {
|
|
||||||
this.logger.debug('silentLogin, trying to get user from redirect callback');
|
|
||||||
// This has to be called when we are in a redirect callback, not on other URLs
|
|
||||||
// if so, we catch the error which will be 'No state in response' and we try to silently signin
|
|
||||||
await this.userManager.signinRedirectCallback();
|
|
||||||
// calling this will fire the userloaded event listener above
|
|
||||||
await this.userManager.getUser();
|
|
||||||
} catch (e) {
|
|
||||||
this.logger.debug('silentLogin, not a signin response, trying to signin now', e);
|
|
||||||
//There is no sign-in response, so we can try to silent login and use refresh token
|
|
||||||
try {
|
|
||||||
//First we try to see if we know this user
|
|
||||||
let user = await this.userManager.getUser();
|
|
||||||
if (user) {
|
|
||||||
this.logger.debug('silentLogin, user is already defined, launching silent signin', user);
|
|
||||||
// If user is defined, we try a silent signin
|
|
||||||
// This will raise a userLoaded event, and so call some code in the listener above...
|
|
||||||
user = await this.userManager.signinSilent();
|
|
||||||
this.logger.debug('silentLogin, user from silent signin', user);
|
|
||||||
// Note: the userloaded listener above should be called from the signinSilent call
|
|
||||||
// if not get the JWT from the user and store the result in the JWT service with the help of callbacks
|
|
||||||
} else {
|
|
||||||
//If no user defined, we try a redirect signin
|
|
||||||
this.logger.debug('silentLogin, user not defined, launching a signin redirect');
|
|
||||||
this.signinRedirect();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
this.logger.debug('silentLogin error, launching a signin redirect', e);
|
|
||||||
// FIXME: We should also be able to show a message to the user with the onSessionExpired listener
|
|
||||||
// In any case if it doesn't work we do a redirect signin
|
|
||||||
this.signinRedirect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async signIn(): Promise<void> {
|
async signIn(): Promise<void> {
|
||||||
this.logger.info('Signin');
|
this.logger.info('Signin');
|
||||||
await this.silentLogin();
|
this.signinRedirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
async signUp(): Promise<void> {
|
async signUp(): Promise<void> {
|
||||||
@@ -267,7 +200,3 @@ export default class OIDCAuthProviderService
|
|||||||
this.params?.onInitialized();
|
this.params?.onInitialized();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDomain(str: string): string {
|
|
||||||
return ((str || '').split('//').pop() || '').split('/').shift() || '';
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import { Transition } from '@headlessui/react';
|
import { Transition } from '@headlessui/react';
|
||||||
import {
|
import {
|
||||||
ChevronLeftIcon,
|
ChevronLeftIcon,
|
||||||
DesktopComputerIcon,
|
|
||||||
DocumentDownloadIcon,
|
DocumentDownloadIcon,
|
||||||
FolderAddIcon,
|
FolderAddIcon,
|
||||||
FolderDownloadIcon,
|
FolderDownloadIcon,
|
||||||
FolderIcon,
|
|
||||||
} from '@heroicons/react/outline';
|
} from '@heroicons/react/outline';
|
||||||
import Avatar from 'app/atoms/avatar';
|
import Avatar from 'app/atoms/avatar';
|
||||||
import A from 'app/atoms/link';
|
import A from 'app/atoms/link';
|
||||||
|
|||||||
Reference in New Issue
Block a user