Skip to content

Add a windowRef option to initLoginFlowInPopup to prevent the window from beeing blocked by popup blockers #965

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Jul 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions docs-src/custom-date-time-provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Custom DateTimeProvider

If your Identity Provider's clock is not synchronized, the validation of the token could fail.
If the deviation is only some seconds, you can use the `AuthConfig.clockSkewInSec` setting to allow a bigger time window deviation.

However, you may need to adjust the base time, that is used for the token validation and make sure, that the `AuthConfig.clockSkewInSec` is still a small reasonable number, then you can implement a custom `DateTimeProvider`.

To do so, create a new service that derives from `DateTimeProvider`:

```typescript
export class MyCustomDateTimeProvider extends DateTimeProvider {
now(): number {
// Return your custom now.
return Date.now();
}

new(): Date {
// Return your custom new Date().
return new Date();
}
}
```

Then, override the provider via dependency injection in your application:

```typescript
@NgModule({
imports: [
// etc.
OAuthModule.forRoot()
],
providers: [
{ provide: DateTimeProvider, useClass: MyCustomDateTimeProvider } // <- add this
],
declarations: [
AppComponent,
// etc.
],
bootstrap: [
AppComponent
]
})
export class AppModule {
}
```
15 changes: 13 additions & 2 deletions docs-src/silent-refresh.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ This simple implementation within silent-refresh.html is sufficient in most case
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;
Expand All @@ -77,12 +76,24 @@ This simple implementation within silent-refresh.html is sufficient in most case

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

(window.opener || window.parent).postMessage(message, location.origin);
if (window.parent && window.parent !== window) {
// if loaded as an iframe during silent refresh
window.parent.postMessage(message, location.origin);
} else if (window.opener && window.opener !== window) {
// if loaded as a popup during initial login
window.opener.postMessage(message, location.origin);
} else {
// last resort for a popup which has been through redirects and can't use window.opener
localStorage.setItem('auth_hash', message);
localStorage.removeItem('auth_hash');
}
</script>
</body>
</html>
```
The above example checks if the message in the URL (either hash or query string) is indeed a message returned with a response from an authentication provider and not an arbitrary value and then attempts to forward this message to a parent widow either by `.parent` (when this html is loaded in an iframe as a result of silent refresh) or by `.opener` (when the html is loaded into a popup during initial login) or finally using a storage event (as a fallback for complex cases, e.g. initial login in a popup with a cross-domain auth provider).


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
134 changes: 134 additions & 0 deletions docs/additional-documentation/custom-datetimeprovider.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>angular-oauth2-oidc</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="icon" type="image/x-icon" href="../images/favicon.ico">
<link rel="stylesheet" href="../styles/style.css">
</head>
<body>

<div class="navbar navbar-default navbar-fixed-top visible-xs">
<a href="../" class="navbar-brand">angular-oauth2-oidc</a>
<button type="button" class="btn btn-default btn-menu ion-ios-menu" id="btn-menu"></button>
</div>

<div class="xs-menu menu" id="mobile-menu">
<div id="book-search-input" role="search"><input type="text" placeholder="Type to search"></div> <compodoc-menu></compodoc-menu>
</div>

<div class="container-fluid main">
<div class="row main">
<div class="hidden-xs menu">
<compodoc-menu mode="normal"></compodoc-menu>
</div>
<!-- START CONTENT -->
<div class="content additional-page">
<div class="content-data">



















<h1 id="custom-datetimeprovider">Custom DateTimeProvider</h1>
<p>If your Identity Provider&#39;s clock is not synchronized, the validation of the token could fail.
If the deviation is only some seconds, you can use the <code>AuthConfig.clockSkewInSec</code> setting to allow a bigger time window deviation.</p>
<p>However, you may need to adjust the base time, that is used for the token validation and make sure, that the <code>AuthConfig.clockSkewInSec</code> is still a small reasonable number, then you can implement a custom <code>DateTimeProvider</code>.</p>
<p>To do so, create a new service that derives from <code>DateTimeProvider</code>:</p>
<div><pre class="line-numbers"><code class="language-typescript">export class MyCustomDateTimeProvider extends DateTimeProvider {
now(): number {
// Return your custom now.
return Date.now();
}

new(): Date {
// Return your custom new Date().
return new Date();
}
}</code></pre></div><p>Then, override the provider via dependency injection in your application:</p>
<div><pre class="line-numbers"><code class="language-typescript">&#64;NgModule({
imports: [
// etc.
OAuthModule.forRoot()
],
providers: [
{ provide: DateTimeProvider, useClass: MyCustomDateTimeProvider } // &lt;- add this
],
declarations: [
AppComponent,
// etc.
],
bootstrap: [
AppComponent
]
})
export class AppModule {
}</code></pre></div>
</div><div class="search-results">
<div class="has-results">
<h1 class="search-results-title"><span class='search-results-count'></span> result-matching "<span class='search-query'></span>"</h1>
<ul class="search-results-list"></ul>
</div>
<div class="no-results">
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
</div>
</div>
</div>
<!-- END CONTENT -->
</div>
</div>

<script>
var COMPODOC_CURRENT_PAGE_DEPTH = 1;
var COMPODOC_CURRENT_PAGE_CONTEXT = 'additional-page';
var COMPODOC_CURRENT_PAGE_URL = 'custom-datetimeprovider.html';
var MAX_SEARCH_RESULTS = 15;
</script>

<script src="../js/libs/custom-elements.min.js"></script>
<script src="../js/libs/lit-html.js"></script>
<!-- Required to polyfill modern browsers as code is ES5 for IE... -->
<script src="../js/libs/custom-elements-es5-adapter.js" charset="utf-8" defer></script>
<script src="../js/menu-wc.js" defer></script>

<script src="../js/libs/bootstrap-native.js"></script>

<script src="../js/libs/es6-shim.min.js"></script>
<script src="../js/libs/EventDispatcher.js"></script>
<script src="../js/libs/promise.min.js"></script>
<script src="../js/libs/zepto.min.js"></script>

<script src="../js/compodoc.js"></script>

<script src="../js/tabs.js"></script>
<script src="../js/menu.js"></script>
<script src="../js/libs/clipboard.min.js"></script>
<script src="../js/libs/prism.js"></script>
<script src="../js/sourceCode.js"></script>
<script src="../js/search/search.js"></script>
<script src="../js/search/lunr.min.js"></script>
<script src="../js/search/search-lunr.js"></script>
<script src="../js/search/search_index.js"></script>
<script src="../js/lazy-load-graphs.js"></script>


</body>
</html>
2 changes: 1 addition & 1 deletion docs/additional-documentation/silent-refresh.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@


<h2 id="refreshing-when-using-implicit-flow-implicit-flow-and-code-flow">Refreshing when using Implicit Flow (Implicit Flow and Code Flow)</h2>
<p><strong>Notes for Code Flow</strong>: You can also use this strategy for refreshing tokens when using code flow. However, please note, the strategy described within <a href="./token-refresh.md">Token Refresh</a> is far easier in this case.</p>
<p><strong>Notes for Code Flow</strong>: You can also use this strategy for refreshing tokens when using code flow. However, please note, the strategy described within <a href="./refreshing-a-token.html">Token Refresh</a> is far easier in this case.</p>
<p>To refresh your tokens when using implicit flow you can use a silent refresh. This is a well-known solution that compensates the fact that implicit flow does not allow for issuing a refresh token. It uses a hidden iframe to get another token from the auth server. When the user is there still logged in (by using a cookie) it will respond without user interaction and provide new tokens.</p>
<p>To use this approach, setup a redirect uri for the silent refresh.</p>
<p>For this, you can set the property silentRefreshRedirectUri in the config object:</p>
Expand Down
Loading