microsoft-authentication-library-for-android: Library fails for B2C login when no Access Token is returned

Using msal:0.2.2

After successfully logged in using B2C method, getting the following exception therefore failure at auth callback:

 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
      at com.microsoft.identity.common.internal.cache.MicrosoftStsAccountCredentialAdapter.getExpiresOn(MicrosoftStsAccountCredentialAdapter.java:231)
      at com.microsoft.identity.common.internal.cache.MicrosoftStsAccountCredentialAdapter.createAccessToken(MicrosoftStsAccountCredentialAdapter.java:78)
      at com.microsoft.identity.common.internal.cache.MicrosoftStsAccountCredentialAdapter.createAccessToken(MicrosoftStsAccountCredentialAdapter.java:45)
      at com.microsoft.identity.common.internal.cache.MsalOAuth2TokenCache.save(MsalOAuth2TokenCache.java:112)
      ...

And here is my raw config file:

{
  "client_id" : "XXX",
  "authorization_user_agent" : "DEFAULT",
  "redirect_uri" : "msalXXX://auth",
  "authorities" : [
    {
      "type": "B2C",
      "authority_url": "https://TTT.b2clogin.com/tfp/TTT.onmicrosoft.com/B2C_1_susi/"
    }
  ]
}

where XXX is client id, and TTT is tenant.

It seems like the field “expires_in” in token response happens to be null, so auth fails inside the library although we get successful response from browser.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 31 (14 by maintainers)

Most upvoted comments

I had similar issue with com.microsoft.identity.client:msal:1.3.0 version, and managed to fix it. In my case the issue was related to the fact the Azure AD B2C returned only Id token without access token, and the expires_on was not presented in the authorisation code exchange JSON response. To get an access token you must provide a valid API scope. To do so, make sure you create the scope under the Expose an API, and also grant permission to that API under the API permissions.

  1. Select App registrations (Preview).
  2. Select the webapi1 application to open its Overview page.
  3. Under Manage, select Expose an API.
  4. Next to Application ID URI, select the Set link.
  5. Replace the default value (a GUID) with api, and then select Save. The full URI is shown, and should be in the format https://your-tenant-name.onmicrosoft.com/api. When your web application requests an access token for the API, it should add this URI as the prefix for each scope that you define for the API.
  6. Under Scopes defined by this API, select Add a scope.
  7. Enter the following values to create a scope that defines read access to the API, then select Add scope:
    1. Scope name: demo.read
    2. Admin consent display name: Read access to demo API
    3. Admin consent description: Allows read access to the demo API
    4. Select Add a scope, enter the following values to add a scope that defines write access to the API, and then select Add scope:
  8. Under API Permission Select Add a permission.
  9. Select the My APIs tab
  10. Select the API to which the web application should be granted access. For example, webapi1.
  11. Under Permission, expand demo, and then select the scopes that you defined earlier. For example, demo.read and demo.write.
  12. Select Add permissions.
  13. Select Grant admin consent for (your tenant name). If you’re prompted to select an account, select your currently signed-in administrator account, or sign in with an account in your Azure AD B2C tenant that’s been assigned at least the Cloud application administrator role.
  14. Select Yes.
  15. Select Refresh, and then verify that “Granted for …” appears under Status for both scopes.

I also recommend you to use the Android studio profiler https://developer.android.com/studio/profile/network-profiler, so you can see the request and the response to the token endpoint.

Your response should look like similar to the following one

image

Please let me know if you need any further explanations,

Yoel

@iambmelt Hello again. So we’ve tried updating the policies with this workaround you gave me. Sadly, when trying to debug all the way down into the LocalMSALController.java, I can see this line:

final TokenResult tokenResult = performTokenRequest(oAuth2Strategy, mAuthorizationRequest, result.getAuthorizationResponse(), parameters);

is giving me a tokenResult that looks like this(in the tokenResponse):

MicrosoftTokenResponse{
mExtExpiresOn=null, 
mClientInfo='STRING_IS_HERE', 
mClientId='null',
mExtendedExpiresIn=null, 
mFamilyId='null'} 
TokenResponse{
mExpiresIn=null, 
mAccessToken='null', 
mTokenType='Bearer', mRefreshToken='ACCESS_TOKEN',
mScope='', 
mState='null', mIdToken='ACCESS_TOKEN',
mResponseReceivedTime=0}

The mClientInfo, mIdToken and mRefreshToken all have data in it, I just removed it for this purpose of the talk.

Hopefully, you can point me in some direction here. 😃

EDIT: I had to set my SCOPES as the client id of the azure b2c project, then it all worked out for me. So this line solved it for me: val SCOPES = arrayOf("CLIENT_ID")