Implementing OAuth Pushed Authorisation Requests in Angular

This posts shows how an Angular application can be secured using Open ID Connect code flow with PKCE and OAuth Pushed Authorisation Requests using node-oidc-provider as the identity provider. This requires configuration on both the client and the identity provider.

Code: par-angular

Getting started using Schematics and angular-auth-oidc-client

The Angular client is implemented using angular-auth-oidc-client.

ng add can be used to add the auth bits to your project.

ng add angular-auth-oidc-client

Then select the configuration you require.

The auth-config.module is now created and the configuration can be completed as required. PAR is activated by using the usePushedAuthorisationRequests configuration. The offline_access scope is requested as well as the prompt=consent. The nonce validation after a refresh is ignored.

export function configureAuth(oidcConfigService: OidcConfigService) {
  return () =>
    oidcConfigService.withConfig({
      stsServer: 'http://localhost:3000',
      redirectUrl: window.location.origin,
      postLogoutRedirectUri: window.location.origin,
      clientId: 'client-par-required',
      usePushedAuthorisationRequests: true, // use par Pushed Authorisation Requests
      scope: 'openid profile offline_access',
      responseType: 'code',
      silentRenew: true,
      useRefreshToken: true,
      logLevel: LogLevel.Debug,
      ignoreNonceAfterRefresh: true,
      customParams: {
        prompt: 'consent', // login, consent
      },
    });
}

The node-oidc-provider client configuration require_pushed_authorization_requests is set to true so that Pushed Authorisation Requests can be used. The node-oidc-provider clients need a configuration for the public client which uses refresh tokens. The grant_types ‘refresh_token’, ‘authorization_code’ are added as well as the offline_access scope. As this is still draft, you need to enable Pushed Authorisation Requests before you can use it.

clients: [
	{
		client_id: 'client-par-required',
		token_endpoint_auth_method: 'none',
		application_type: 'web',
		grant_types: ['refresh_token', 'authorization_code'],
		redirect_uris: ['https://localhost:4207'],
		require_pushed_authorization_requests: true,
		scope: 'openid offline_access profile email',
		post_logout_redirect_uris: [
		  'https://localhost:4207'
		]
	},
],
features: {
	devInteractions: { enabled: false }, // defaults to true

	deviceFlow: { enabled: true }, // defaults to false
	introspection: { enabled: true }, // defaults to false
	revocation: { enabled: true }, // defaults to false

	pushedAuthorizationRequests: { enabled: true },

},

When the authentication begins, the well known endpoints is used to get the PAR endpoint. The property pushed_authorization_request_endpoint will be set if this is supported.

http://localhost:3000/.well-known/openid-configuration


{
	"pushed_authorization_request_endpoint":"http://localhost:3000/request",
	"authorization_endpoint":"http://localhost:3000/auth",
	"token_endpoint":"http://localhost:3000/token"	
	"issuer":"http://localhost:3000",
	"jwks_uri":"http://localhost:3000/jwks",
	"userinfo_endpoint":"http://localhost:3000/me",
	"introspection_endpoint":"http://localhost:3000/token/introspection",
	
	// ... more

The PAR request is sent using the same parameters as OIDC code flow, but in the body of the request. As this is a public client, the client is not authorized. This was also configured in the IDP.

client_id=client-par-required
&redirect_uri=https://localhost:4207
&response_type=code
&scope=openid profile offline_access
&nonce=73a2f7 + ...
&code_challenge=aLo8v3vvenGVmXwecG3-rhuYATGTrKBKnMmXHayXpHI
&code_challenge_method=S256
&prompt=consent

All configured correctly, the PAR response will contain the url to the server session for this auth request.

{
	expires_in: 300, 
	request_uri: "urn:ietf:params:oauth:request_uri:oeSbJ-jn1QvsTW9EUsAasmypWj7-PQEp7RjxogiCWUo"
}

The client then redirects to the authorization endpoint and the flow continues like the existing standard.

http://localhost:3000/auth?
request_uri=urn%3Aietf%3Aparams%3Aoauth%3Arequest_uri%3AoeSbJ-jn1QvsTW9EUsAasmypWj7-PQEp7RjxogiCWUo
&client_id=client-par-required

That’s all the configuration required. The OAuth Pushed Authorisation Requests is still in draft and so might change. Hopefully this will get rolled out and more identity providers will support this specification.

The next steps would be to use OAuth RAR in the PAR request.

Links:

https://github.com/panva/node-oidc-provider

https://github.com/damienbod/angular-auth-oidc-client

https://tools.ietf.org/html/draft-ietf-oauth-par-06

https://www.connect2id.com/products/server/docs/api/par

View at Medium.com

2 comments

  1. […] Implementing OAuth Pushed Authorisation Requests in Angular – Damien Bowden […]

  2. […] Implementing OAuth Pushed Authorization Requests in Angular (Damien Bowden) […]

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.