Skip to content

Commit

Permalink
Merge pull request #770 from Varada-Schneider/master
Browse files Browse the repository at this point in the history
There is no explicit way to revoke an access token when the user logs out
  • Loading branch information
manfredsteyer authored Mar 28, 2020
2 parents 5dd15e1 + c799ead commit 5abcd07
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 4 deletions.
5 changes: 5 additions & 0 deletions projects/lib/src/auth.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ export class AuthConfig {
*/
public tokenEndpoint?: string = null;

/**
* Url of the revocation endpoint as defined by OpenId Connect and OAuth 2.
*/
public revocationEndpoint?: string = null;

/**
* Names of known parameters sent out in the TokenResponse. https://tools.ietf.org/html/rfc6749#section-5.1
*/
Expand Down
3 changes: 2 additions & 1 deletion projects/lib/src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export type EventType =
| 'session_terminated'
| 'logout'
| 'popup_closed'
| 'popup_blocked';
| 'popup_blocked'
| 'token_revoke_error';

export abstract class OAuthEvent {
constructor(readonly type: EventType) {}
Expand Down
78 changes: 75 additions & 3 deletions projects/lib/src/oauth-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ export class OAuthService extends AuthConfig implements OnDestroy {

this.discoveryDocumentLoaded = true;
this.discoveryDocumentLoadedSubject.next(doc);
this.revocationEndpoint = doc.revocation_endpoint;

if (this.sessionChecksEnabled) {
this.restartSessionChecksIfStillLoggedIn();
Expand Down Expand Up @@ -625,6 +626,14 @@ export class OAuthService extends AuthConfig implements OnDestroy {
);
}

errors = this.validateUrlFromDiscoveryDocument(doc.revocation_endpoint);
if (errors.length > 0) {
this.logger.error(
'error validating revocation_endpoint in discovery document',
errors
);
}

errors = this.validateUrlFromDiscoveryDocument(doc.userinfo_endpoint);
if (errors.length > 0) {
this.logger.error(
Expand Down Expand Up @@ -804,7 +813,8 @@ export class OAuthService extends AuthConfig implements OnDestroy {
this.storeAccessTokenResponse(
tokenResponse.access_token,
tokenResponse.refresh_token,
tokenResponse.expires_in,
tokenResponse.expires_in ||
this.fallbackAccessTokenExpirationTimeInSec,
tokenResponse.scope,
this.extractRecognizedCustomParameters(tokenResponse)
);
Expand Down Expand Up @@ -890,7 +900,8 @@ export class OAuthService extends AuthConfig implements OnDestroy {
this.storeAccessTokenResponse(
tokenResponse.access_token,
tokenResponse.refresh_token,
tokenResponse.expires_in,
tokenResponse.expires_in ||
this.fallbackAccessTokenExpirationTimeInSec,
tokenResponse.scope,
this.extractRecognizedCustomParameters(tokenResponse)
);
Expand Down Expand Up @@ -1729,7 +1740,8 @@ export class OAuthService extends AuthConfig implements OnDestroy {
this.storeAccessTokenResponse(
tokenResponse.access_token,
tokenResponse.refresh_token,
tokenResponse.expires_in,
tokenResponse.expires_in ||
this.fallbackAccessTokenExpirationTimeInSec,
tokenResponse.scope,
this.extractRecognizedCustomParameters(tokenResponse)
);
Expand Down Expand Up @@ -2538,4 +2550,64 @@ export class OAuthService extends AuthConfig implements OnDestroy {
});
return foundParameters;
}

/**
* Revokes the auth token to secure the vulnarability
* of the token issued allowing the authorization server to clean
* up any security credentials associated with the authorization
*/
public revokeTokenAndLogout(): Promise<any> {
let revoke_endpoint = this.revocationEndpoint;
let current_access_token = this.getAccessToken();
let params = new HttpParams()
.set('token', current_access_token)
.set('token_type_hint', 'access_token');

let headers = new HttpHeaders().set(
'Content-Type',
'application/x-www-form-urlencoded'
);

if (this.useHttpBasicAuth) {
const header = btoa(`${this.clientId}:${this.dummyClientSecret}`);
headers = headers.set('Authorization', 'Basic ' + header);
}

if (!this.useHttpBasicAuth) {
params = params.set('client_id', this.clientId);
}

if (!this.useHttpBasicAuth && this.dummyClientSecret) {
params = params.set('client_secret', this.dummyClientSecret);
}

if (this.customQueryParams) {
for (const key of Object.getOwnPropertyNames(this.customQueryParams)) {
params = params.set(key, this.customQueryParams[key]);
}
}

return new Promise((resolve, reject) => {
if (current_access_token) {
this.http
.post<any>(revoke_endpoint, params, { headers })
.subscribe(
res => {
this.logOut();
resolve(res);
this.logger.info('Token successfully revoked');
},
err => {
this.logger.error('Error revoking token', err);
this.eventsSubject.next(
new OAuthErrorEvent('token_revoke_error', err)
);
reject(err);
}
);
} else {
this.logger.warn('User not logged in to revoke token.');
}
});
}
}
1 change: 1 addition & 0 deletions projects/lib/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,5 @@ export interface OidcDiscoveryDoc {
claims_parameter_supported: boolean;
service_documentation: string;
ui_locales_supported: string[];
revocation_endpoint: string;
}

0 comments on commit 5abcd07

Please sign in to comment.