This section shows how to use the password flow, which demands the user to directly enter his or her password into the client.
Please note that from an OAuth2/OIDC perspective, the code flow is better suited for logging into a SPA and the flow described here should only be used, when a) there is a strong trust relations ship between the client and the auth server and when b) other flows are not possible.
Please also note that with OAuth 2.1, password flow will be deprecated.
To configure the library you just have to set some properties on startup. For this, the following sample uses the constructor of the AppComponent which is called before routing kicks in.
Please not, that this configuration is quite similar to the one for the implcit flow.
@Component({ ... })
export class AppComponent {
constructor(private oauthService: OAuthService) {
// The SPA's id. Register SPA with this id at the auth-server
this.oauthService.clientId = "demo-resource-owner";
// set the scope for the permissions the client should request
// The auth-server used here only returns a refresh token (see below), when the scope offline_access is requested
this.oauthService.scope = "openid profile email voucher offline_access";
// Use setStorage to use sessionStorage or another implementation of the TS-type Storage
// instead of localStorage
this.oauthService.setStorage(sessionStorage);
// Set a dummy secret
// Please note that the auth-server used here demand the client to transmit a client secret, although
// the standard explicitly cites that the password flow can also be used without it. Using a client secret
// does not make sense for a SPA that runs in the browser. That's why the property is called dummyClientSecret
// Using such a dummy secret is as safe as using no secret.
this.oauthService.dummyClientSecret = "geheim";
// Load Discovery Document and then try to login the user
let url = 'https://steyer-identity-server.azurewebsites.net/identity/.well-known/openid-configuration';
this.oauthService.loadDiscoveryDocument(url).then(() => {
// Do what ever you want here
});
}
}
In cases where you don't have an OIDC based discovery document you have to configure some more properties manually:
@Component({ ... })
export class AppComponent {
constructor(private oauthService: OAuthService) {
// Login-Url
this.oauthService.tokenEndpoint = "https://steyer-identity-server.azurewebsites.net/identity/connect/token";
// Url with user info endpoint
// This endpont is described by OIDC and provides data about the loggin user
// This sample uses it, because we don't get an id_token when we use the password flow
// If you don't want this lib to fetch data about the user (e. g. id, name, email) you can skip this line
this.oauthService.userinfoEndpoint = "https://steyer-identity-server.azurewebsites.net/identity/connect/userinfo";
// The SPA's id. Register SPA with this id at the auth-server
this.oauthService.clientId = "demo-resource-owner";
// set the scope for the permissions the client should request
this.oauthService.scope = "openid profile email voucher offline_access";
// Set a dummy secret
// Please note that the auth-server used here demand the client to transmit a client secret, although
// the standard explicitly cites that the password flow can also be used without it. Using a client secret
// does not make sense for a SPA that runs in the browser. That's why the property is called dummyClientSecret
// Using such a dummy secret is as safe as using no secret.
this.oauthService.dummyClientSecret = "geheim";
}
}
this.oauthService.fetchTokenUsingPasswordFlow('max', 'geheim').then((resp) => {
// Loading data about the user
return this.oauthService.loadUserProfile();
}).then(() => {
// Using the loaded user data
let claims = this.oAuthService.getIdentityClaims();
if (claims) console.debug('given_name', claims.given_name);
})
There is also a short form for fetching the token and loading the user profile:
this.oauthService.fetchTokenUsingPasswordFlowAndLoadUserProfile('max', 'geheim').then(() => {
let claims = this.oAuthService.getIdentityClaims();
if (claims) console.debug('given_name', claims.given_name);
});
Using the password flow you MIGHT get a refresh token (which isn't the case with the implicit flow by design!). You can use this token later to get a new access token, e. g. after it expired.
this.oauthService.refreshToken().then(() => {
console.debug('ok');
})