Skip to content

Commit

Permalink
feat(session checks): Session checks work now for code flow too. Pls …
Browse files Browse the repository at this point in the history
…see Docs for details.
  • Loading branch information
manfredsteyer committed Mar 22, 2020
1 parent 71b705c commit 4bf8901
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 29 deletions.
10 changes: 0 additions & 10 deletions docs-src/popup.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,4 @@ Thanks to a great community contribution, this library also supports logging the
Also, for your ``silent-regfesh.html``, make sure you are also targeting
``window.opener`` and fall back to ``window.parent``:

```html
<html>
<body>
<script>
(window.opener || window.parent).postMessage(location.hash || ('#' + location.search), location.origin);
</script>
</body>
</html>
```

**Please note**: IE sets opener to null under specific security settings. This prevents making this work.
6 changes: 6 additions & 0 deletions docs-src/session-checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export const authConfig: AuthConfig = {
}
```

## Refresh

Please note that the lib performs a token refresh when the session changes to get the newest information about the current session. When using implicit flow, this means you have to configure [silent refresh](./silent-refresh.html); when using code flow you either need silent refresh or a [refresh token](./refreshing-a-token.html).

If using refresh tokens, your Auth Server needs to bind them to the current session's lifetime. Unfortunately, the used version of Identity Server 4, shown in the docs and in the example applications, does not support this at the moment.

## Events
To get notified, you can hook up for the event ``session_terminated``:

Expand Down
25 changes: 25 additions & 0 deletions docs-src/silent-refresh.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,31 @@ This file is loaded into the hidden iframe after getting new tokens. Its only ta
</html>
```

This simple implementation within silent-refresh.html is sufficient in most cases. It takes care of the hash fragment as well as of the query string (property search). For **edge cases** you need to check if the received hash fragment is a token response. For this, please go with the following **more advanced implementation**:

```html
<html>
<body>
<script>
var checks = [/[\?|&|#]code=/, /[\?|&|#]error=/, /[\?|&|#]token=/, /[\?|&|#]id_token=/];
function isResponse(str) {
var count = 0;
if (!str) return false;
for(var i=0; i<checks.length; i++) {
if (str.match(checks[i])) return true;
}
return false;
}
var message = isResponse(location.hash) ? location.hash : '#' + location.search;
(window.opener || window.parent).postMessage(message, location.origin);
</script>
</body>
</html>
```

Please make sure that this file is copied to your output directory by your build task. When using the CLI you can define it as an asset for this. For this, you have to add the following line to the file ``.angular-cli.json``:

```JSON
Expand Down
29 changes: 18 additions & 11 deletions projects/lib/src/oauth-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1090,7 +1090,9 @@ export class OAuthService extends AuthConfig implements OnDestroy {
'wrong origin',
origin,
'expected',
issuer
issuer,
'event',
e
);

return;
Expand Down Expand Up @@ -1127,10 +1129,20 @@ export class OAuthService extends AuthConfig implements OnDestroy {
}

protected handleSessionChange(): void {
/* events: session_changed, relogin, stopTimer, logged_out*/
this.eventsSubject.next(new OAuthInfoEvent('session_changed'));
this.stopSessionCheckTimer();
if (this.silentRefreshRedirectUri) {

if (!this.useSilentRefresh && this.responseType === 'code') {
this.refreshToken()
.then(_ => {
this.debug('token refresh after session change worked');
})
.catch(_ => {
this.debug('token refresh did not work after session changed');
this.eventsSubject.next(new OAuthInfoEvent('session_terminated'));
this.logOut(true);
});
} else if (this.silentRefreshRedirectUri) {
this.silentRefresh().catch(_ =>
this.debug('silent refresh failed after session changed')
);
Expand Down Expand Up @@ -1519,15 +1531,10 @@ export class OAuthService extends AuthConfig implements OnDestroy {
return Promise.reject(event);
}

this.storeSessionState(sessionState);

if (code) {
return new Promise((resolve, reject) => {
this.getTokenFromCode(code, options).then(result => {
this.storeSessionState(sessionState);
resolve();
}).catch(err => {
reject(err);
});
});
return this.getTokenFromCode(code, options).then(_ => null);
} else {
return Promise.resolve();
}
Expand Down
3 changes: 1 addition & 2 deletions projects/sample/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export class AppComponent {
console.debug('state', this.oauthService.state);
this.oauthService.loadUserProfile();
});

}

private configureCodeFlow() {
Expand All @@ -39,7 +38,7 @@ export class AppComponent {
this.oauthService.loadDiscoveryDocumentAndTryLogin();

// Optional
this.oauthService.setupAutomaticSilentRefresh();
// this.oauthService.setupAutomaticSilentRefresh();

}

Expand Down
2 changes: 2 additions & 0 deletions projects/sample/src/app/auth-code-flow.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export const authCodeFlowConfig: AuthConfig = {

showDebugInformation: true,

sessionChecksEnabled: true,

timeoutFactor: 0.01,
// disablePKCI: true,

Expand Down
2 changes: 1 addition & 1 deletion projects/sample/src/app/auth.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const authConfig: AuthConfig = {

showDebugInformation: true,

sessionChecksEnabled: false,
sessionChecksEnabled: true,

// timeoutFactor: 0.01,
};
15 changes: 13 additions & 2 deletions projects/sample/src/app/home/home.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ <h2>Login with Implicit Flow in popup</h2>
<button class="btn btn-default" (click)="loginImplicitInPopup()">Login</button>
<button class="btn btn-default" (click)="logout()">Logout</button>
</p>
<b>Username/Password:</b> max/geheim
<p>
<b>Username/Password:</b> max/geheim
</p>
<p>
<b>Note:</b> When using IE, some security settings block the communication with popups. This prevents that this feature works.
</p>
</div>
</div>

Expand All @@ -57,7 +62,13 @@ <h2>Login with Code Flow in popup</h2>
<button class="btn btn-default" (click)="loginCodeInPopup()">Login</button>
<button class="btn btn-default" (click)="logout()">Logout</button>
</p>
<b>Username/Password:</b> alice/alice
<p>
<b>Username/Password:</b> alice/alice
</p>
<p>
<b>Note:</b> When using IE, some security settings block the communication with popups. This prevents that this feature works.
</p>

</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion projects/sample/src/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ export const useHash = false;

// Set this to true, to use silent refresh; otherwise the example
// uses the refresh_token via an AJAX coll to get new tokens.
export const useSilentRefreshForCodeFlow = false;
export const useSilentRefreshForCodeFlow = true;
17 changes: 15 additions & 2 deletions projects/sample/src/silent-refresh.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
<html>
<body>
<script>
(window.opener || window.parent).postMessage(location.hash || ('#' + location.search), location.origin);
var checks = [/[\?|&|#]code=/, /[\?|&|#]error=/, /[\?|&|#]token=/, /[\?|&|#]id_token=/];

function isResponse(str) {
var count = 0;
if (!str) return false;
for(var i=0; i<checks.length; i++) {
if (str.match(checks[i])) return true;
}
return false;
}

var message = isResponse(location.hash) ? location.hash : '#' + location.search;

(window.opener || window.parent).postMessage(message, location.origin);
</script>
</body>
</html>
</html>

0 comments on commit 4bf8901

Please sign in to comment.