mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-10 11:33:04 +00:00
Store available authentication methods in ngrx/store
This commit is contained in:
@@ -65,16 +65,53 @@ export class AuthInterceptor implements HttpInterceptor {
|
|||||||
return http.url && http.url.endsWith('/authn/logout');
|
return http.url && http.url.endsWith('/authn/logout');
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseAuthMethodsfromHeaders(headers: HttpHeaders): AuthMethodModel[] {
|
private parseShibbolethLocation(unparsedLocation: string): string {
|
||||||
console.log('parseAuthMethodsfromHeaders(): ', headers);
|
let parsedLocation = '';
|
||||||
// errorHeaders
|
unparsedLocation = unparsedLocation.trim();
|
||||||
return [];
|
unparsedLocation = unparsedLocation.replace('location="', '');
|
||||||
|
unparsedLocation = unparsedLocation.replace('"', '');
|
||||||
|
let re = /%3A%2F%2F/g;
|
||||||
|
unparsedLocation = unparsedLocation.replace(re, '://');
|
||||||
|
re = /%3A/g
|
||||||
|
unparsedLocation = unparsedLocation.replace(re, ':')
|
||||||
|
parsedLocation = unparsedLocation + '/shibboleth';
|
||||||
|
|
||||||
|
return parsedLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private makeAuthStatusObject(authenticated: boolean, accessToken?: string, error?: string, location?: string, httpHeaders?: HttpHeaders, ): AuthStatus {
|
private parseAuthMethodsfromHeaders(headers: HttpHeaders): AuthMethodModel[] {
|
||||||
|
// console.log('parseAuthMethodsfromHeaders(): ', headers);
|
||||||
|
const authMethodModels: AuthMethodModel[] = [];
|
||||||
|
const parts: string[] = headers.get('www-authenticate').split(',');
|
||||||
|
console.log('parts: ', parts);
|
||||||
|
// get the login methods names
|
||||||
|
// tslint:disable-next-line:forin
|
||||||
|
for (const i in parts) {
|
||||||
|
const part: string = parts[i].trim();
|
||||||
|
if (part.includes('realm')) {
|
||||||
|
const methodName = part.split(' ')[0];
|
||||||
|
const authMethod: AuthMethodModel = new AuthMethodModel(methodName);
|
||||||
|
// check if the authentication method is shibboleth
|
||||||
|
// if so the next part is the shibboleth location
|
||||||
|
// e.g part i: shibboleth realm="DSpace REST API", part i+1: location="/Shibboleth.sso/Login?target=https%3A%2F%2Flocalhost%3A8080"
|
||||||
|
if (methodName.includes('shibboleth')) {
|
||||||
|
console.log('Index 2: ', parts[2]);
|
||||||
|
const location: string = this.parseShibbolethLocation(parts[+i + 1]); // +1: unaray + operator is necessaray because i is a string, the operator works like parseInt()
|
||||||
|
// console.log('shib location: ', location);
|
||||||
|
authMethod.location = location;
|
||||||
|
}
|
||||||
|
authMethodModels.push(authMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('Array of AuthMethodModels: ', authMethodModels);
|
||||||
|
return authMethodModels;
|
||||||
|
}
|
||||||
|
|
||||||
|
private makeAuthStatusObject(authenticated: boolean, accessToken?: string, error?: string, location?: string, httpHeaders?: HttpHeaders,): AuthStatus {
|
||||||
const authStatus = new AuthStatus();
|
const authStatus = new AuthStatus();
|
||||||
|
|
||||||
const authMethods: AuthMethodModel[] = this.parseAuthMethodsfromHeaders(httpHeaders);
|
const authMethods: AuthMethodModel[] = this.parseAuthMethodsfromHeaders(httpHeaders);
|
||||||
|
authStatus.authMethods = authMethods;
|
||||||
authStatus.id = null;
|
authStatus.id = null;
|
||||||
|
|
||||||
authStatus.okay = true;
|
authStatus.okay = true;
|
||||||
@@ -193,7 +230,7 @@ export class AuthInterceptor implements HttpInterceptor {
|
|||||||
}
|
}
|
||||||
// Create a new HttpResponse and return it, so it can be handle properly by AuthService.
|
// Create a new HttpResponse and return it, so it can be handle properly by AuthService.
|
||||||
const authResponse = new HttpResponse({
|
const authResponse = new HttpResponse({
|
||||||
body: this.makeAuthStatusObject(false, null, error.error, location, error.headers ),
|
body: this.makeAuthStatusObject(false, null, error.error, location, error.headers),
|
||||||
headers: error.headers,
|
headers: error.headers,
|
||||||
status: error.status,
|
status: error.status,
|
||||||
statusText: error.statusText,
|
statusText: error.statusText,
|
||||||
|
@@ -14,6 +14,7 @@ import {
|
|||||||
// import models
|
// import models
|
||||||
import { EPerson } from '../eperson/models/eperson.model';
|
import { EPerson } from '../eperson/models/eperson.model';
|
||||||
import { AuthTokenInfo } from './models/auth-token-info.model';
|
import { AuthTokenInfo } from './models/auth-token-info.model';
|
||||||
|
import {AuthMethodModel} from './models/auth-method.model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The auth state.
|
* The auth state.
|
||||||
@@ -50,6 +51,10 @@ export interface AuthState {
|
|||||||
|
|
||||||
// the authenticated user
|
// the authenticated user
|
||||||
user?: EPerson;
|
user?: EPerson;
|
||||||
|
|
||||||
|
// all authenticationMethods enabled at the backend
|
||||||
|
authMethods?: AuthMethodModel[];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,7 +64,8 @@ const initialState: AuthState = {
|
|||||||
authenticated: false,
|
authenticated: false,
|
||||||
loaded: false,
|
loaded: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
ssoLoginUrl: ''
|
ssoLoginUrl: '',
|
||||||
|
authMethods: new Array<AuthMethodModel>()
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -200,15 +206,16 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
|
|||||||
|
|
||||||
// next three cases are used by shibboleth login
|
// next three cases are used by shibboleth login
|
||||||
case AuthActionTypes.RETRIEVE_AUTH_METHODS:
|
case AuthActionTypes.RETRIEVE_AUTH_METHODS:
|
||||||
console.log(' case AuthActionTypes.RETRIEVE_AUTH_METHODS');
|
console.log('case AuthActionTypes.RETRIEVE_AUTH_METHODS');
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
loading: true
|
loading: true
|
||||||
});
|
});
|
||||||
|
|
||||||
case AuthActionTypes.RETRIEVE_AUTH_METHODS_SUCCESS:
|
case AuthActionTypes.RETRIEVE_AUTH_METHODS_SUCCESS:
|
||||||
|
console.log('case RETRIEVE_AUTH_METHODS_SUCCESS');
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
loading: false,
|
loading: false,
|
||||||
ssoLoginUrl: (action as RetrieveAuthMethodsSuccessAction).payload
|
authMethods: (action as RetrieveAuthMethodsSuccessAction).payload
|
||||||
});
|
});
|
||||||
|
|
||||||
case AuthActionTypes.RETRIEVE_AUTH_METHODS_ERROR:
|
case AuthActionTypes.RETRIEVE_AUTH_METHODS_ERROR:
|
||||||
|
@@ -24,6 +24,7 @@ import {Base64EncodeUrl} from '../../shared/utils/encode-decode.util';
|
|||||||
import {RemoteDataBuildService} from '../cache/builders/remote-data-build.service';
|
import {RemoteDataBuildService} from '../cache/builders/remote-data-build.service';
|
||||||
import {GlobalConfig} from '../../../config/global-config.interface';
|
import {GlobalConfig} from '../../../config/global-config.interface';
|
||||||
import {GLOBAL_CONFIG} from '../../../config';
|
import {GLOBAL_CONFIG} from '../../../config';
|
||||||
|
import {AuthMethodModel} from './models/auth-method.model';
|
||||||
|
|
||||||
export const LOGIN_ROUTE = '/login';
|
export const LOGIN_ROUTE = '/login';
|
||||||
export const LOGOUT_ROUTE = '/logout';
|
export const LOGOUT_ROUTE = '/logout';
|
||||||
@@ -222,19 +223,19 @@ export class AuthService {
|
|||||||
* Retrieve authentication methods available
|
* Retrieve authentication methods available
|
||||||
* @returns {User}
|
* @returns {User}
|
||||||
*/
|
*/
|
||||||
public retrieveAuthMethods(): Observable<string> {
|
public retrieveAuthMethods(): Observable<AuthMethodModel[]> {
|
||||||
console.log('auth.service retrieveAuthMethods() was called');
|
console.log('auth.service retrieveAuthMethods() was called');
|
||||||
// return this.authRequestService.getRequest('login').pipe(
|
// return this.authRequestService.getRequest('login').pipe(
|
||||||
return this.authRequestService.postToEndpoint('login', {}).pipe(
|
return this.authRequestService.postToEndpoint('login', {}).pipe(
|
||||||
map((status: AuthStatus) => {
|
map((status: AuthStatus) => {
|
||||||
let url = '';
|
let authMethods: AuthMethodModel[];
|
||||||
if (isNotEmpty(status.ssoLoginUrl)) {
|
if (isNotEmpty(status.authMethods)) {
|
||||||
// url = this.parseSSOLocation(status.ssoLoginUrl);
|
// url = this.parseSSOLocation(status.ssoLoginUrl);
|
||||||
// console.log('Parsed SSOLoginUrl: ', url);
|
// console.log('Parsed SSOLoginUrl: ', url);
|
||||||
// url = 'https://fis.tiss.tuwien.ac.at/Shibboleth.sso/Login?target=https://fis.tiss.tuwien.ac.at';
|
// url = 'https://fis.tiss.tuwien.ac.at/Shibboleth.sso/Login?target=https://fis.tiss.tuwien.ac.at';
|
||||||
url = status.ssoLoginUrl;
|
authMethods = status.authMethods;
|
||||||
}
|
}
|
||||||
return url;
|
return authMethods;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,9 @@
|
|||||||
export class AuthMethodModel {
|
export class AuthMethodModel {
|
||||||
authMethodName: string;
|
authMethodName: string;
|
||||||
location?: string;
|
location?: string;
|
||||||
|
|
||||||
|
constructor(authMethodName: string, location?: string) {
|
||||||
|
this.authMethodName = authMethodName;
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,8 +53,9 @@ export class AuthStatus implements CacheableObject {
|
|||||||
*/
|
*/
|
||||||
self: string;
|
self: string;
|
||||||
|
|
||||||
ssoLoginUrl: string;
|
/**
|
||||||
|
* All authentication methods enabled at the backend
|
||||||
|
*/
|
||||||
authMethods: AuthMethodModel[];
|
authMethods: AuthMethodModel[];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user