6
votes

I'm developing an SPA with Azure AD B2C as the identity provider. I'm using the MSAL JavaScript library and it's mostly working fine. I can create users, log in and get access tokens for my Web API back-end.

The only issue at the moment is that the B2C endpoint is not returning refresh tokens so when the access token expires, the acquireTokenSilent method in the UserAgentApplication class, which is meant to refresh expired access tokens using the refresh token, fails.

My application in B2C is configured with "Include web app / web API" and "Allow implicit flow" set to "Yes" in its Properties. In the API Access section, both the "openid" and "offline_access" scopes are ticked under "Access the user's profile". The application itself has "read", "write" and "user_impersonation" scopes (not sure if that matters).

enter image description here

"offline_access" is included in my scopes and I event tried creating an application one, like the read/write scopes and include that as well (as "https://mytenant.onmicrosoft.com/testapp/offline_access") but nothing seems to work. The responses never have a refresh token, neither for the id token not for the access token.

What I have noticed is that when I go to the SignUp-SignIn policy I created and try to run the endpoint from there, the "offline_access" scope isn't even available in the drop-down. Even if I copy the "run endpoint" link at the bottom and add the scope to the URL before running it, the response doesn't include a refresh token.

enter image description here

When I click on the link at the top, it seems to give me some details about the endpoint and only "openid" is under the supported scopes.

Not sure what I'm missing here so any ideas would be appreciated.

1

1 Answers

9
votes

The Run Now link generates an auth request that uses the implicit flow to log in. Implicit flows, by definition, do not allow you to obtain a refresh token due to security reasons. Therefore, the drop down does not give you the offline_access scope since it won't work. If you want a refresh token, you need to run through the confidential code flow. If you choose to, you can do this by manually modifying the URL that the "Run now" link generates. Specifically, in the URL:

  1. Set response_type=code (not token)

  2. Add "offline_access" to the list of scopes

Once you obtain a code, make a POST request as shown in the documentation to exchange the code for a refresh token.