mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
Use status request to check an existing token and to retrieve auth methods available
This commit is contained in:
@@ -85,6 +85,15 @@ export class AuthInterceptor implements HttpInterceptor {
|
||||
return http.url && http.url.endsWith('/authn/logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if response is from a status request
|
||||
*
|
||||
* @param http
|
||||
*/
|
||||
private isStatusResponse(http: HttpRequest<any> | HttpResponseBase): boolean {
|
||||
return http.url && http.url.endsWith('/authn/status');
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract location url from the WWW-Authenticate header
|
||||
*
|
||||
@@ -202,8 +211,10 @@ export class AuthInterceptor implements HttpInterceptor {
|
||||
|
||||
const authService = this.inj.get(AuthService);
|
||||
|
||||
const token = authService.getToken();
|
||||
let newReq;
|
||||
const token: AuthTokenInfo = authService.getToken();
|
||||
let newReq: HttpRequest<any>;
|
||||
let updateReq: any = {};
|
||||
let authorization: string;
|
||||
|
||||
if (authService.isTokenExpired()) {
|
||||
authService.setRedirectUrl(this.router.url);
|
||||
@@ -224,11 +235,13 @@ export class AuthInterceptor implements HttpInterceptor {
|
||||
}
|
||||
});
|
||||
// Get the auth header from the service.
|
||||
const Authorization = authService.buildAuthHeader(token);
|
||||
authorization = authService.buildAuthHeader(token);
|
||||
// Clone the request to add the new header.
|
||||
newReq = req.clone({headers: req.headers.set('authorization', Authorization)});
|
||||
newReq = req.clone({ headers: req.headers.set('authorization', authorization) });
|
||||
} else {
|
||||
const updateReq = this.isAuthRequest(req) ? { withCredentials: true } : {};
|
||||
if (this.isAuthRequest(req)) {
|
||||
updateReq = { withCredentials: true };
|
||||
}
|
||||
newReq = req.clone(updateReq);
|
||||
}
|
||||
|
||||
@@ -237,19 +250,29 @@ export class AuthInterceptor implements HttpInterceptor {
|
||||
// tap((response) => console.log('next.handle: ', response)),
|
||||
map((response) => {
|
||||
// Intercept a Login/Logout response
|
||||
if (response instanceof HttpResponse && this.isSuccess(response) && (this.isLoginResponse(response) || this.isLogoutResponse(response))) {
|
||||
if (response instanceof HttpResponse && this.isSuccess(response) && this.isAuthRequest(response)) {
|
||||
// It's a success Login/Logout response
|
||||
let authRes: HttpResponse<any>;
|
||||
if (this.isLoginResponse(response)) {
|
||||
// login successfully
|
||||
const newToken = response.headers.get('authorization');
|
||||
authRes = response.clone({body: this.makeAuthStatusObject(true, newToken)});
|
||||
authRes = response.clone({
|
||||
body: this.makeAuthStatusObject(true, newToken)
|
||||
});
|
||||
|
||||
// clean eventually refresh Requests list
|
||||
this.refreshTokenRequestUrls = [];
|
||||
} else if (this.isStatusResponse(response)) {
|
||||
authRes = response.clone({
|
||||
body: Object.assign(response.body, {
|
||||
authMethods: this.parseAuthMethodsFromHeaders(response.headers)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// logout successfully
|
||||
authRes = response.clone({body: this.makeAuthStatusObject(false)});
|
||||
authRes = response.clone({
|
||||
body: this.makeAuthStatusObject(false)
|
||||
});
|
||||
}
|
||||
return authRes;
|
||||
} else {
|
||||
|
@@ -16,7 +16,13 @@ import { AuthStatus } from './models/auth-status.model';
|
||||
import { AuthTokenInfo, TOKENITEM } from './models/auth-token-info.model';
|
||||
import { isEmpty, isNotEmpty, isNotNull, isNotUndefined } from '../../shared/empty.util';
|
||||
import { CookieService } from '../services/cookie.service';
|
||||
import { getAuthenticationToken, getRedirectUrl, isAuthenticated, isTokenRefreshing } from './selectors';
|
||||
import {
|
||||
getAuthenticationMethods,
|
||||
getAuthenticationToken,
|
||||
getRedirectUrl,
|
||||
isAuthenticated,
|
||||
isTokenRefreshing
|
||||
} from './selectors';
|
||||
import { AppState, routerStateSelector } from '../../app.reducer';
|
||||
import {
|
||||
CheckAuthenticationTokenAction,
|
||||
@@ -28,6 +34,7 @@ import { Base64EncodeUrl } from '../../shared/utils/encode-decode.util';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { RouteService } from '../services/route.service';
|
||||
import { AuthMethod } from './models/auth.method';
|
||||
import { NormalizedAuthStatus } from './models/normalized-auth-status.model';
|
||||
|
||||
export const LOGIN_ROUTE = '/login';
|
||||
export const LOGOUT_ROUTE = '/logout';
|
||||
@@ -121,7 +128,14 @@ export class AuthService {
|
||||
* Checks if token is present into the request cookie
|
||||
*/
|
||||
public checkAuthenticationCookie(): Observable<AuthStatus> {
|
||||
return this.authRequestService.postToEndpoint('login');
|
||||
// Determine if the user has an existing auth session on the server
|
||||
const options: HttpOptions = Object.create({});
|
||||
let headers = new HttpHeaders();
|
||||
headers = headers.append('Accept', 'application/json');
|
||||
options.headers = headers;
|
||||
return this.authRequestService.getRequest('status', options).pipe(
|
||||
map((status: NormalizedAuthStatus) => Object.assign(new AuthStatus(), status))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,7 +172,13 @@ export class AuthService {
|
||||
* Checks if token is present into browser storage and is valid. (NB Check is done only on SSR)
|
||||
*/
|
||||
public checkAuthenticationToken() {
|
||||
this.store.pipe(
|
||||
select(getAuthenticationMethods),
|
||||
filter((authMethods: AuthMethod[]) => isEmpty(authMethods)),
|
||||
take(1)
|
||||
).subscribe(() => {
|
||||
this.store.dispatch(new CheckAuthenticationTokenAction());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -4,6 +4,7 @@ import { mapsTo, relationship } from '../../cache/builders/build-decorators';
|
||||
import { NormalizedObject } from '../../cache/models/normalized-object.model';
|
||||
import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer';
|
||||
import { EPerson } from '../../eperson/models/eperson.model';
|
||||
import { AuthMethod } from './auth.method';
|
||||
|
||||
@mapsTo(AuthStatus)
|
||||
@inheritSerialization(NormalizedObject)
|
||||
@@ -39,4 +40,9 @@ export class NormalizedAuthStatus extends NormalizedObject<AuthStatus> {
|
||||
@autoserialize
|
||||
eperson: string;
|
||||
|
||||
/**
|
||||
* All authentication methods enabled at the backend
|
||||
*/
|
||||
@autoserialize
|
||||
authMethods: AuthMethod[];
|
||||
}
|
||||
|
@@ -225,6 +225,8 @@ export class AuthPostRequest extends PostRequest {
|
||||
}
|
||||
|
||||
export class AuthGetRequest extends GetRequest {
|
||||
forceBypassCache = true;
|
||||
|
||||
constructor(uuid: string, href: string, public options?: HttpOptions) {
|
||||
super(uuid, href, null, options);
|
||||
}
|
||||
|
Reference in New Issue
Block a user