Skip to content

Commit 4780734

Browse files
Merge branch 'master' into improve-default-oauth-interceptor
2 parents 79b36af + 01b4f20 commit 4780734

File tree

133 files changed

+19753
-45806
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

133 files changed

+19753
-45806
lines changed

.vscode/launch.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "chrome",
9+
"request": "launch",
10+
"name": "Launch Chrome against localhost",
11+
"url": "http://localhost:4200",
12+
"webRoot": "${workspaceFolder}"
13+
}
14+
]
15+
}

.vscode/settings.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@
2525
"typescriptreact",
2626
"yml"
2727
],
28-
"spellright.language": "de",
28+
"spellright.language": [
29+
"en"
30+
],
2931
"spellright.documentTypes": [
3032
"latex",
31-
"plaintext"
33+
"plaintext",
34+
"markdown"
3235
]
3336
}

README.md

+18-25
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,18 @@ Successfully tested with **Angular 7** and its Router, PathLocationStrategy as w
3737
## Contributions
3838
- Feel free to file pull requests
3939
- The closed issues contain some ideas for PRs and enhancements (see labels)
40+
- If you want to contribute to the docs, you can do so in the `docs-src` folder. Make sure you update `summary.json` as well. Then generate the docs with the following commands:
41+
42+
```
43+
npm install -g @compodoc/compodoc
44+
npm run docs
45+
```
4046

4147
# Features
42-
- Logging in via OAuth2 and OpenId Connect (OIDC) Implicit Flow (where a user is redirected to Identity Provider)
48+
- Logging in via Implicit Flow (where a user is redirected to Identity Provider)
49+
- Logging in via Code Flow + PKCE
4350
- "Logging in" via Password Flow (where a user enters their password into the client)
44-
- Token Refresh for Password Flow by using a Refresh Token
51+
- Token Refresh for all supported flows
4552
- Automatically refreshing a token when/some time before it expires
4653
- Querying Userinfo Endpoint
4754
- Querying Discovery Document to ease configuration
@@ -116,7 +123,7 @@ export const authConfig: AuthConfig = {
116123
// URL of the SPA to redirect the user to after login
117124
redirectUri: window.location.origin + '/index.html',
118125

119-
// The SPA's id. The SPA is registerd with this id at the auth-server
126+
// The SPA's id. The SPA is registered with this id at the auth-server
120127
clientId: 'spa-demo',
121128

122129
// set the scope for the permissions the client should request
@@ -125,7 +132,7 @@ export const authConfig: AuthConfig = {
125132
}
126133
```
127134

128-
Configure the OAuthService with this config object when the application starts up:
135+
Configure the ``OAuthService`` with this config object when the application starts up:
129136

130137
```TypeScript
131138
import { OAuthService } from 'angular-oauth2-oidc';
@@ -140,10 +147,10 @@ import { Component } from '@angular/core';
140147
export class AppComponent {
141148

142149
constructor(private oauthService: OAuthService) {
143-
this.configureWithNewConfigApi();
150+
this.configure();
144151
}
145152

146-
private configureWithNewConfigApi() {
153+
private configure() {
147154
this.oauthService.configure(authConfig);
148155
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
149156
this.oauthService.loadDiscoveryDocumentAndTryLogin();
@@ -168,7 +175,7 @@ export class HomeComponent {
168175
}
169176

170177
public login() {
171-
this.oauthService.initImplicitFlow();
178+
this.oauthService.initLoginFlow();
172179
}
173180

174181
public logoff() {
@@ -215,23 +222,7 @@ This directly redirects the user to the identity server if there are no valid to
215222

216223
### Calling a Web API with an Access Token
217224

218-
Pass this Header to the used method of the ``Http``-Service within an Instance of the class ``Headers``:
219-
220-
```TypeScript
221-
var headers = new Headers({
222-
"Authorization": "Bearer " + this.oauthService.getAccessToken()
223-
});
224-
```
225-
226-
If you are using the new ``HttpClient``, use the class ``HttpHeaders`` instead:
227-
228-
```TypeScript
229-
var headers = new HttpHeaders({
230-
"Authorization": "Bearer " + this.oauthService.getAccessToken()
231-
});
232-
```
233-
234-
Since 3.1 you can also automate this task by switching ``sendAccessToken`` on and by setting ``allowedUrls`` to an array with prefixes for the respective URLs. Use lower case for the prefixes.
225+
You can automate this task by switching ``sendAccessToken`` on and by setting ``allowedUrls`` to an array with prefixes for the respective URLs. Use lower case for the prefixes.
235226

236227
```TypeScript
237228
OAuthModule.forRoot({
@@ -242,11 +233,13 @@ OAuthModule.forRoot({
242233
})
243234
```
244235

236+
If you need more versatility, you can look in the [documentation](https://manfredsteyer.github.io/angular-oauth2-oidc/docs/additional-documentation/working-with-httpinterceptors.html) how to setup a custom interceptor.
237+
245238
## Routing
246239

247240
If you use the ``PathLocationStrategy`` (which is on by default) and have a general catch-all-route (``path: '**'``) you should be fine. Otherwise look up the section ``Routing with the HashStrategy`` in the [documentation](https://manfredsteyer.github.io/angular-oauth2-oidc/docs/).
248241

249-
## More Documentation
242+
## More Documentation (!)
250243

251244
See the [documentation](https://manfredsteyer.github.io/angular-oauth2-oidc/docs/) for more information about this library.
252245

angular.json

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "./node_modules/@angular-devkit/core/src/workspace/workspace-schema.json",
2+
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
33
"version": 1,
44
"newProjectRoot": "projects",
55
"projects": {
@@ -21,14 +21,6 @@
2121
}
2222
}
2323
},
24-
"test": {
25-
"builder": "@angular-devkit/build-angular:karma",
26-
"options": {
27-
"main": "projects/lib/src/test.ts",
28-
"tsConfig": "projects/lib/tsconfig.spec.json",
29-
"karmaConfig": "projects/lib/karma.conf.js"
30-
}
31-
},
3224
"lint": {
3325
"builder": "@angular-devkit/build-angular:tslint",
3426
"options": {
@@ -114,7 +106,8 @@
114106
"tsConfig": "projects/sample/tsconfig.spec.json",
115107
"karmaConfig": "projects/sample/karma.conf.js",
116108
"styles": [
117-
"projects/sample/styles.css"
109+
"projects/sample/src/styles.css",
110+
"node_modules/bootstrap/dist/css/bootstrap.css"
118111
],
119112
"scripts": [],
120113
"assets": [

docs-src/code-flow.bak.md

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Code Flow
2+
3+
Since Version 8, this library also supports code flow and [PKCE](https://tools.ietf.org/html/rfc7636) to align with the current draft of the [OAuth 2.0 Security Best Current Practice](https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13) document.
4+
5+
6+
To configure your solution for code flow + PKCE you have to set the `responseType` to `code`:
7+
8+
```TypeScript
9+
10+
import { AuthConfig } from 'angular-oauth2-oidc';
11+
12+
export const authCodeFlowConfig: AuthConfig = {
13+
// Url of the Identity Provider
14+
issuer: 'https://demo.identityserver.io',
15+
16+
// URL of the SPA to redirect the user to after login
17+
redirectUri: window.location.origin + '/index.html',
18+
19+
// The SPA's id. The SPA is registerd with this id at the auth-server
20+
// clientId: 'server.code',
21+
clientId: 'spa',
22+
23+
// Just needed if your auth server demands a secret. In general, this
24+
// is a sign that the auth server is not configured with SPAs in mind
25+
// and it might not enforce further best practices vital for security
26+
// such applications.
27+
// dummyClientSecret: 'secret',
28+
29+
responseType: 'code',
30+
31+
// set the scope for the permissions the client should request
32+
// The first four are defined by OIDC.
33+
// Important: Request offline_access to get a refresh token
34+
// The api scope is a usecase specific one
35+
scope: 'openid profile email offline_access api',
36+
37+
showDebugInformation: true,
38+
39+
// Not recommented:
40+
// disablePKCI: true,
41+
};
42+
```
43+
44+
After this, you can initialize the code flow using:
45+
46+
```TypeScript
47+
48+
this.oauthService.initCodeFlow();
49+
```
50+
51+
There is also a convenience method `initLoginFlow` which initializes either the code flow or the implicit flow depending on your configuration.
52+
53+
```TypeScript
54+
this.oauthService.initLoginFlow();
55+
```
56+
57+
Also -- as shown in the readme -- you have to execute the following code when bootstrapping to make the library to fetch the token:
58+
59+
```TypeScript
60+
this.oauthService.configure(authCodeFlowConfig);
61+
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
62+
this.oauthService.loadDiscoveryDocumentAndTryLogin();
63+
```
64+
65+
66+

docs-src/code-flow.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Code Flow
2+
3+
Since Version 8, this library also supports code flow and [PKCE](https://tools.ietf.org/html/rfc7636) to align with the current draft of the [OAuth 2.0 Security Best Current Practice](https://tools.ietf.org/html/draft-ietf-oauth-security-topics-13) document.
4+
5+
6+
To configure your solution for code flow + PKCE you have to set the `responseType` to `code`:
7+
8+
```TypeScript
9+
import { AuthConfig } from 'angular-oauth2-oidc';
10+
11+
export const authCodeFlowConfig: AuthConfig = {
12+
// Url of the Identity Provider
13+
issuer: 'https://demo.identityserver.io',
14+
15+
// URL of the SPA to redirect the user to after login
16+
redirectUri: window.location.origin + '/index.html',
17+
18+
// The SPA's id. The SPA is registerd with this id at the auth-server
19+
// clientId: 'server.code',
20+
clientId: 'spa',
21+
22+
// Just needed if your auth server demands a secret. In general, this
23+
// is a sign that the auth server is not configured with SPAs in mind
24+
// and it might not enforce further best practices vital for security
25+
// such applications.
26+
// dummyClientSecret: 'secret',
27+
28+
responseType: 'code',
29+
30+
// set the scope for the permissions the client should request
31+
// The first four are defined by OIDC.
32+
// Important: Request offline_access to get a refresh token
33+
// The api scope is a usecase specific one
34+
scope: 'openid profile email offline_access api',
35+
36+
showDebugInformation: true,
37+
38+
// Not recommented:
39+
// disablePKCI: true,
40+
};
41+
```
42+
43+
After this, you can initialize the code flow using:
44+
45+
```TypeScript
46+
this.oauthService.initCodeFlow();
47+
```
48+
49+
There is also a convenience method `initLoginFlow` which initializes either the code flow or the implicit flow depending on your configuration.
50+
51+
```TypeScript
52+
this.oauthService.initLoginFlow();
53+
```
54+
55+
Also -- as shown in the readme -- you have to execute the following code when bootstrapping to make the library to fetch the token:
56+
57+
```TypeScript
58+
this.oauthService.configure(authCodeFlowConfig);
59+
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
60+
this.oauthService.loadDiscoveryDocumentAndTryLogin();
61+
```
62+
63+
64+
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Configure custom OAuthStorage
2+
3+
This library uses `sessionStorage` as the default storage provider. You can customize this by using `localStorage` or your own storage solution.
4+
5+
## Using localStorage
6+
If you want to use `localStorage` instead of `sessionStorage`, you can add a provider to your AppModule. This works as follows:
7+
8+
```TypeScript
9+
import { HttpClientModule } from '@angular/common/http';
10+
import { OAuthModule } from 'angular-oauth2-oidc';
11+
// etc.
12+
13+
// We need a factory, since localStorage is not available during AOT build time.
14+
export function storageFactory() : OAuthStorage {
15+
return localStorage
16+
}
17+
18+
@NgModule({
19+
imports: [
20+
// etc.
21+
HttpClientModule,
22+
OAuthModule.forRoot()
23+
],
24+
declarations: [
25+
AppComponent,
26+
HomeComponent,
27+
// etc.
28+
],
29+
bootstrap: [
30+
AppComponent
31+
],
32+
providers: [
33+
{ provide: OAuthStorage, useFactory: storageFactory }
34+
]
35+
})
36+
export class AppModule {
37+
}
38+
```
39+
40+
## Custom storage solution
41+
42+
If you want to use a custom storage solution, you can extend the `OAuthStorage` class. Documentation can be found [here](../classes/OAuthStorage.html#info). Then add it as a provider, just like in the `localStorage` example above.
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Discovery Document Validation
2+
3+
The configuration parameter `strictDiscoveryDocumentValidation` is set `true` by default. This ensures that all of the endpoints provided via the ID Provider discovery document share the same base URL as the `issuer` parameter.
4+
5+
Several ID Providers (i.e. Google OpenID, WS02-IS, PingOne) provide different domains or path params for various endpoints in the discovery document. These providers may still adhere to the [OpenID Connect Provider Configuration specification](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse), but will fail to pass this library's discovery document validation.
6+
7+
To use this library with an ID Provider that does not maintain a consistent base URL across the discovery document endpoints, set the `strictDiscoveryDocumentValidation` parameter to `false` in your configuration:
8+
9+
```TypeScript
10+
import { AuthConfig } from 'angular-oauth2-oidc';
11+
12+
export const authConfig: AuthConfig = {
13+
14+
// Url of the Identity Provider
15+
issuer: 'https://steyer-identity-server.azurewebsites.net/identity',
16+
17+
// URL of the SPA to redirect the user to after login
18+
redirectUri: window.location.origin + '/index.html',
19+
20+
// The SPA's id. The SPA is registerd with this id at the auth-server
21+
clientId: 'spa-demo',
22+
23+
// set the scope for the permissions the client should request
24+
// The first three are defined by OIDC. The 4th is a usecase-specific one
25+
scope: 'openid profile email voucher',
26+
27+
// turn off validation that discovery document endpoints start with the issuer url defined above
28+
strictDiscoveryDocumentValidation: false
29+
}
30+
```

0 commit comments

Comments
 (0)