Added backend lookup if shibboleth is enabled

This commit is contained in:
Julius Gruber
2019-06-25 13:10:19 +02:00
parent 14419ca567
commit 26f01d6f8f
10 changed files with 46 additions and 37 deletions

View File

@@ -29,13 +29,13 @@ module.exports = {
timePerMethod: {'PATCH': 3} //time in seconds timePerMethod: {'PATCH': 3} //time in seconds
} }
}, },
// Authentications /* // Authentications
auth: { auth: {
target: { target: {
host: 'https://fis.tiss.tuwien.ac.at', host: 'https://fis.tiss.tuwien.ac.at',
page: '' page: ''
} }
}, },*/
// Form settings // Form settings
form: { form: {
// NOTE: Map server-side validators to comparative Angular form validators // NOTE: Map server-side validators to comparative Angular form validators

View File

@@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import {ShibbLoginAction} from '../../core/auth/auth.actions'; import {GetJWTafterShibbLoginAction} from '../../core/auth/auth.actions';
import {Store} from '@ngrx/store'; import {Store} from '@ngrx/store';
import {CoreState} from '../../core/core.reducers'; import {CoreState} from '../../core/core.reducers';
@@ -13,7 +13,7 @@ export class ShibbolethComponent implements OnInit {
constructor( private store: Store<CoreState>,) { } constructor( private store: Store<CoreState>,) { }
ngOnInit() { ngOnInit() {
this.store.dispatch(new ShibbLoginAction()); this.store.dispatch(new GetJWTafterShibbLoginAction());
} }
} }

View File

@@ -57,11 +57,11 @@ export class AuthenticateAction implements Action {
} }
/** /**
* ShibbLoginAction. * GetJWTafterShibbLoginAction.
* @class ShibbLoginAction * @class GetJWTafterShibbLoginAction
* @implements {Action} * @implements {Action}
*/ */
export class ShibbLoginAction implements Action { export class GetJWTafterShibbLoginAction implements Action {
public type: string = AuthActionTypes.SHIBB_LOGIN; public type: string = AuthActionTypes.SHIBB_LOGIN;
} }
@@ -380,7 +380,7 @@ export class SetRedirectUrlAction implements Action {
*/ */
export type AuthActions export type AuthActions
= AuthenticateAction = AuthenticateAction
| ShibbLoginAction | GetJWTafterShibbLoginAction
| AuthenticatedAction | AuthenticatedAction
| AuthenticatedErrorAction | AuthenticatedErrorAction
| AuthenticatedSuccessAction | AuthenticatedSuccessAction

View File

@@ -30,7 +30,7 @@ import {
RetrieveAuthMethodsAction, RetrieveAuthMethodsAction,
RetrieveAuthMethodsErrorAction, RetrieveAuthMethodsErrorAction,
RetrieveAuthMethodsSuccessAction, RetrieveAuthMethodsSuccessAction,
ShibbLoginAction GetJWTafterShibbLoginAction
} from './auth.actions'; } from './auth.actions';
import { EPerson } from '../eperson/models/eperson.model'; import { EPerson } from '../eperson/models/eperson.model';
import { AuthStatus } from './models/auth-status.model'; import { AuthStatus } from './models/auth-status.model';
@@ -65,7 +65,7 @@ export class AuthEffects {
@Effect() @Effect()
public shibbLogin$: Observable<Action> = this.actions$.pipe( public shibbLogin$: Observable<Action> = this.actions$.pipe(
ofType(AuthActionTypes.SHIBB_LOGIN), ofType(AuthActionTypes.SHIBB_LOGIN),
switchMap((action: ShibbLoginAction) => { switchMap((action: GetJWTafterShibbLoginAction) => {
return this.authService.startShibbAuth().pipe( return this.authService.startShibbAuth().pipe(
take(1), take(1),
map((response: AuthStatus) => new AuthenticationSuccessAction(response.token)), map((response: AuthStatus) => new AuthenticationSuccessAction(response.token)),

View File

@@ -34,9 +34,6 @@ export class AuthInterceptor implements HttpInterceptor {
constructor(private inj: Injector, private router: Router, private store: Store<AppState>) { constructor(private inj: Injector, private router: Router, private store: Store<AppState>) {
} }
private is405AuthResponse(response: HttpResponseBase): boolean {
return response.status === 405;
}
private is302Response(response: HttpResponseBase): boolean { private is302Response(response: HttpResponseBase): boolean {
return response.status === 302; return response.status === 302;
@@ -59,7 +56,8 @@ export class AuthInterceptor implements HttpInterceptor {
} }
private isLoginResponse(http: HttpRequest<any> | HttpResponseBase): boolean { private isLoginResponse(http: HttpRequest<any> | HttpResponseBase): boolean {
return http.url && http.url.endsWith('/authn/login'); return http.url && http.url.endsWith('/authn/login')
/*|| http.url.endsWith('/shibboleth');*/
} }
private isLogoutResponse(http: HttpRequest<any> | HttpResponseBase): boolean { private isLogoutResponse(http: HttpRequest<any> | HttpResponseBase): boolean {
@@ -81,17 +79,27 @@ export class AuthInterceptor implements HttpInterceptor {
return authStatus; return authStatus;
} }
private getSSOLocationfromHeader(header: HttpHeaders): string { private getShibbUrlFromHeader(header: HttpHeaders): string {
console.log('HEADER www-authenticate: ', header.get('www-authenticate')); // console.log('HEADER www-authenticate: ', header.get('www-authenticate'));
let location = ''; let shibbolethUrl = '';
if (header.get('www-authenticate').startsWith('shibboleth realm')) { if (header.get('www-authenticate').startsWith('shibboleth realm')) {
const strings = header.get('www-authenticate').split(','); let urlParts: string[] = header.get('www-authenticate').split(',');
location = strings[1]; let location = urlParts[1];
let re = /"/g;
location = location.replace(re, '').trim();
location = location.replace('location=', ''); location = location.replace('location=', '');
console.log('This should be the location: ', location); // console.log('location: ', location);
return location = location.replace('"', '').trim(); urlParts = location.split('?');
const host = urlParts[1].replace('target=', '');
console.log('host: ', host);
shibbolethUrl = host + location + '/shibboleth';
re = /%3A%2F%2F/g;
shibbolethUrl = shibbolethUrl.replace(re, '://');
// console.log('shibbolethUrl: ', shibbolethUrl);
return shibbolethUrl;
} }
return location; return shibbolethUrl;
} }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
@@ -159,11 +167,6 @@ export class AuthInterceptor implements HttpInterceptor {
// Intercept an error response // Intercept an error response
if (error instanceof HttpErrorResponse) { if (error instanceof HttpErrorResponse) {
// Check for 405
/* if (this.is405AuthResponse(error)) {
console.log('the caught error is a 405');
}*/
// Checks if is a response from a request to an authentication endpoint // Checks if is a response from a request to an authentication endpoint
if (this.isAuthRequest(error)) { if (this.isAuthRequest(error)) {
console.log('catchError isAuthRequest=true'); console.log('catchError isAuthRequest=true');
@@ -171,8 +174,8 @@ export class AuthInterceptor implements HttpInterceptor {
this.refreshTokenRequestUrls = []; this.refreshTokenRequestUrls = [];
// console.log('error: ', error); // console.log('error: ', error);
let location = ''; let location = '';
if (error.headers.get('www-authenticate') != null) { if (error.headers.get('www-authenticate') != null && error.headers.get('www-authenticate').includes('shibboleth realm')) {
location = this.getSSOLocationfromHeader(error.headers); location = this.getShibbUrlFromHeader(error.headers);
} }
// 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({

View File

@@ -231,15 +231,15 @@ export class AuthService {
if (isNotEmpty(status.ssoLoginUrl)) { if (isNotEmpty(status.ssoLoginUrl)) {
// 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; url = status.ssoLoginUrl;
} }
return url; return url;
}) })
) )
} }
private parseSSOLocation(url: string): string { /* private parseSSOLocation(url: string): string {
console.log('auth.service parseSSOLocation was called'); console.log('auth.service parseSSOLocation was called');
const parseUrl = decodeURIComponent(url); const parseUrl = decodeURIComponent(url);
// const urlTree: UrlTree = this.router.parseUrl(url); // const urlTree: UrlTree = this.router.parseUrl(url);
@@ -252,7 +252,7 @@ export class AuthService {
// console.log(url); // console.log(url);
const target = `?target=${this.config.auth.target.host}${this.config.auth.target.page}`; const target = `?target=${this.config.auth.target.host}${this.config.auth.target.page}`;
return parseUrl.replace(/\?target=http.+/g, target); return parseUrl.replace(/\?target=http.+/g, target);
} }*/
/** /**
* Create a new user * Create a new user

View File

@@ -53,6 +53,7 @@ export class AuthenticatedGuard implements CanActivate, CanLoad {
} }
private handleAuth(url: string): Observable<boolean> { private handleAuth(url: string): Observable<boolean> {
console.log('authenticated.guard.handleAuth() was called with url: ', url);
// get observable // get observable
const observable = this.store.pipe(select(isAuthenticated)); const observable = this.store.pipe(select(isAuthenticated));

View File

@@ -0,0 +1,5 @@
export class AuthShibbModel {
host: string;
target: string;
startShibSessionUrl: string; // as configured in backend
}

View File

@@ -33,13 +33,13 @@
</div> </div>
<div> <!-- <div>
<br> <br>
<a class="btn btn-lg btn-primary btn-block mt-2" <a class="btn btn-lg btn-primary btn-block mt-2"
href="https://fis.tiss.tuwien.ac.at/Shibboleth.sso/Login?target=https://fis.tiss.tuwien.ac.at/shibboleth" href="https://fis.tiss.tuwien.ac.at/Shibboleth.sso/Login?target=https://fis.tiss.tuwien.ac.at/shibboleth"
role="button" role="button"
>HardCoded Shibb</a> >HardCoded Shibb</a>
</div> </div>-->
<!-- <div > <!-- <div >

View File

@@ -6,7 +6,7 @@ import {select, Store} from '@ngrx/store';
import {Observable} from 'rxjs'; import {Observable} from 'rxjs';
import { import {
AuthenticateAction, AuthenticateAction,
ResetAuthenticationMessagesAction, ShibbLoginAction ResetAuthenticationMessagesAction, GetJWTafterShibbLoginAction
} from '../../core/auth/auth.actions'; } from '../../core/auth/auth.actions';
import { import {
@@ -234,7 +234,7 @@ export class LogInComponent implements OnDestroy, OnInit {
dispatchShibbLoginAction() { dispatchShibbLoginAction() {
console.log('dispatchShibbLoginAction() was called'); console.log('dispatchShibbLoginAction() was called');
// const ssoLoginUrl = 'https://fis.tiss.tuwien.ac.at/Shibboleth.sso/Login' // const ssoLoginUrl = 'https://fis.tiss.tuwien.ac.at/Shibboleth.sso/Login'
this.store.dispatch(new ShibbLoginAction()); this.store.dispatch(new GetJWTafterShibbLoginAction());
// this.store.dispatch(new AuthenticateAction(email, password)); // this.store.dispatch(new AuthenticateAction(email, password));
} }