Azure / azure-sdk-for-java

This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
MIT License
2.3k stars 1.96k forks source link

[BUG] No way to add code verifier in AuthorizationCodeCredential through its builder. #33235

Open durgadas54 opened 1 year ago

durgadas54 commented 1 year ago

Describe the bug I am able to get authorization code by sending code_chanllenge. But when trying to get token for graph client, I am using the AuthorizationCodeCredential. The getToken method of this class don't pass code verifier to request. This result in error "The code_verifier does not match the code_challenge supplied in the authorization request for PKCE.".

Exception or Stack Trace Caused by: com.microsoft.aad.msal4j.MsalInteractionRequiredException: AADSTS70008: The provided authorization code or refresh token has expired due to inactivity. Send a new interactive authorization request for this user and resource.

at com.microsoft.aad.msal4j.MsalServiceExceptionFactory.fromHttpResponse(MsalServiceExceptionFactory.java:39)
at com.microsoft.aad.msal4j.TokenRequestExecutor.createAuthenticationResultFromOauthHttpResponse(TokenRequestExecutor.java:103)
at com.microsoft.aad.msal4j.TokenRequestExecutor.executeTokenRequest(TokenRequestExecutor.java:34)
at com.microsoft.aad.msal4j.AbstractClientApplicationBase.acquireTokenCommon(AbstractClientApplicationBase.java:128)
at com.microsoft.aad.msal4j.AcquireTokenByAuthorizationGrantSupplier.execute(AcquireTokenByAuthorizationGrantSupplier.java:63)
at com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:69)
at com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:18)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)
... 6 more

To Reproduce Received authorization Code by passing code challenge https://login.microsoftonline.com/%s/oauth2/v2.0/authorize?scope=https://graph.microsoft.com/.default&response_type=code&client_id=%s&prompt=select_account&redirect_uri=%s&code_challenge_method=S256

Now to use graph client :

TokenCredential tokenCredential= new AuthorizationCodeCredentialBuilder() .clientId("id") .tenantId("tenantId") .authorizationCode("codefrombrowser") .redirectUrl(pkceConnectionDto.getRedirectUrl()) .build();

        final TokenCredentialAuthProvider tokenCredentialAuthProvider =
                getTokenCredentialAuthProvider(
                        getScopes(), tokenCredential);

        GraphServiceClient client =
                GraphServiceClient.builder()
                        .authenticationProvider(tokenCredentialAuthProvider)
                        .buildClient();
        **List<User> users = client.users().buildRequest().get().getCurrentPage();** // error here 

Similar issue has been fixed for python sdk it seems : https://github.com/Azure/azure-sdk-for-python/issues/13834

joshfree commented 1 year ago

@g2vinay can you please investigate this issue reported by @durgadas54?

/cc @billwert related: https://github.com/Azure/azure-sdk-for-python/issues/13834

durgadas54 commented 1 year ago

any updates here?

joshfree commented 1 year ago

@g2vinay as we chatted about offline, please take a look.

g2vinay commented 1 year ago

Thank you @durgadas54 for reporting this issue. Apologies for the delay in getting to it. I am investigating this issue and will provide updates on mitigation soon.

durgadas54 commented 1 year ago

Thanks @g2vinay @joshfree . Appreciate you taking time to look into it. As we allow code_challege in in authorization code call there should be some provision to pass it through builder for token call.

tanios13 commented 1 month ago

Hello, I am using python and would also like to use PKCE with authorization code and not interactive browser. I am doing the following:

code_verifier = secrets.token_urlsafe(64)
    code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode('utf-8').rstrip('=')
    session['code_verifier'] = code_verifier

    auth_url = msal_app.get_authorization_request_url(
        ["User.Read"],
        redirect_uri=REDIRECT_URI,
        code_challenge=code_challenge,
        code_challenge_method='S256'
    )

and getting the result:

result = msal_app.acquire_token_by_authorization_code(
                request.args['code'],
                scopes=["User.Read"],
                redirect_uri=REDIRECT_URI,
                data={'code_verifier': session['code_verifier']}
            )

However, I am getting:

"The Code_Verifier does not match the code_challenge supplied in the authorization request."

Any guidance?