Why does acquiring an Azure AD token by refresh token have no signing algorithm?

1.7k Views Asked by At

When I get a token by authorization code (authContext.acquireTokenByAuthorizationCode), I get a JWT (idToken) that is signed and has the proper headers:

{
  "typ": "JWT",
  "alg": "RS256",
  "x5t": "wLLmYfsqdQuWtV_-hnVtDJJZM3Q",
  "kid": "wLLmYfsqdQuWtV_-hnVtDJJZM3Q"
}

but when I use the refresh token to get a new token (authContext.acquireTokenByRefreshToken(...)), it returns an unsigned JWT:

{
  "typ": "JWT",
  "alg": "none"
}

How do I get it to give me a signed JWT?

return authContext.acquireTokenByRefreshToken( refreshToken, new ClientCredentials( clientId, clientSecret ), null );

1

There are 1 best solutions below

2
On BEST ANSWER

I did not reproduce your issue on my side. I followed this tutorial to get Authentication code and acquire access token and refresh token with below code successfully. Please refer to it.

import com.microsoft.aad.adal4j.AuthenticationContext;
import com.microsoft.aad.adal4j.AuthenticationResult;
import com.microsoft.aad.adal4j.ClientCredential;

import java.net.URI;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class GetTokenByAuthenticationCode {

    private static final String APP_ID = "***";
    private static final String APP_SECRET = "***";
    private static final String REDIRECT_URI = "http://localhost:8080";
    private static final String tenant = "***";

    public static void main(String[] args) throws Exception {

        String authority = "https://login.microsoftonline.com/" + tenant + "/oauth2/authorize";
        ExecutorService service = Executors.newFixedThreadPool(1);

        String code = "***";

        AuthenticationContext context = new AuthenticationContext(authority, true, service);

        URI url = new URI(REDIRECT_URI);

        Future<AuthenticationResult> result = context.acquireTokenByAuthorizationCode(
                code,
                url,
                new ClientCredential(APP_ID, APP_SECRET),
                null
        );
        String token = result.get().getAccessToken();
        System.out.println(token);
        String refreshToken = result.get().getRefreshToken();
        System.out.println(refreshToken);


        Future<AuthenticationResult> result1 = context.acquireTokenByRefreshToken(
                refreshToken,
                new ClientCredential(APP_ID, APP_SECRET),
                null
        );

        String tokenNew = result1.get().getAccessToken();
        String refreshTokenNew = result1.get().getRefreshToken();
        System.out.println(tokenNew);
        System.out.println(refreshTokenNew);
    }
}

Decode:

enter image description here


Update Answer:

Firstly, sorry for the mistake. I replaced getIdToken with getAccessToken, the result is as same as you.Then I searched the response parameters in Authorize access to Azure Active Directory web applications using the OAuth 2.0 code grant flow, you could find the statement of id_token parameter.

An unsigned JSON Web Token (JWT) representing an ID token. The app can base64Url decode the segments of this token to request information about the user who signed in. The app can cache the values and display them, but it should not rely on them for any authorization or security boundaries.

So, the id token just a segment which can't be relied on. If you want to get the complete id token, please refer to the openId flow.