IdentityModel / oidc-client-js

OpenID Connect (OIDC) and OAuth2 protocol support for browser-based JavaScript applications
Apache License 2.0
2.43k stars 840 forks source link

Refreshing an access token with Azure AD fails #1264

Open slieschke opened 3 years ago

slieschke commented 3 years ago

I'm building a SPA that's using oidc-client to authenticate to Azure AD using the OAuth 2.0 authorization code flow with PKCE to obtain an access token to use a custom (Java) API.

In order to be able to validate the access token I created a custom scope as explained under the Problem 1: Azure AD returns invalid JWT access token section at Making Azure AD OIDC Compliant and passed it as my UserManager scope so it is included when authorizing. I got authorizing and requesting initial access and refresh tokens all working as expected.

However when refreshing an access token using the /{tenant}/oauth2/v2.0/token resource I received a 400 Bad Request response containing this error message:

AADSTS90009: Application 'redacted-client-id'(redacted-client-id) is requesting a token for itself. This scenario is supported only if resource is specified using the GUID based App Identifier.

Per this discussion the error message is misleading, and Azure AD actually requires a scope parameter to be passed with the request per their documentation for refreshing the access token. I confirmed that providing my custom scope in a scope solved this problem by using Fiddler to manually add it into the request made by oidc-client before sending it onto Azure AD, and I successfully had my access token refreshed.

What would you think of adding an optional setting flag like includeScopeInTokenRefresh that could be used to send the scope from the settings with access token refresh requests?

EloHg commented 3 years ago

Hello, I am having this exact issue. @slieschke did you find a workaround or did you end up using a different library? @brockallen Any idea of when this enhancement could be done? Thanks!

slieschke commented 3 years ago

@EloHg I've worked around this by patching signinSilent at runtime:

const originalSignInSilent = userManager.signinSilent.bind(userManager);
userManager.signinSilent = () => originalSignInSilent({ scope: '<scope value>' });

I've also got an oidc-client-js enhancement that adds a includeScopeInTokenRefresh option at https://github.com/IdentityModel/oidc-client-js/compare/dev...slieschke:support-azure-ad-access-token-refresh. I'm holding off raising a PR at this point however as I've noticed Microsoft's docs now state that the scope parameter is optional when refreshing the access token, however I still get the same error if I don't provide it. I've asked here for further clarification about this.