Closed darrenjrobinson closed 2 years ago
I should also mention that I also tried obtaining an Authorization Code and then using the -AuthorizationCode option in Get-MsalToken to get the access token.
Example
$msalParams = @{
grant_type = "authorization_code";
code_verifier = $pkceCodes.code_verifier;
}
Import-Module MSAL.PS
$clientSecretEncoded = ConvertTo-SecureString -String $clientSecret -AsPlainText -Force
Get-MsalToken -ClientId $clientID `
-ClientSecret $clientSecretEncoded `
-AuthorizationCode $authCode `
-TenantId $tenantID `
-RedirectUri $replyURL `
-ExtraQueryParameters $msalParams `
-Authority "https://login.microsoftonline.com/$($tenantID)/oauth2/v2.0/token" `
-Verbose -Debug
The error returned is:
Get-MsalToken:
Line |
2 | Get-MsalToken -ClientId $clientID `
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| AADSTS50148: The code_verifier does not match the code_challenge supplied in the authorization request for PKCE.
Trace ID: 785ac559-cda4-4c2c-8297-e67f053d1b00
Correlation ID: 6eca98e6-47d2-4bac-ab73-7dda251cd481
Timestamp: 2021-12-22 04:49:33Z
The code_verifier I have generated is correct which I verified by doing a POST call to "https://login.microsoftonline.com/$($tenantID)/oauth2/v2.0/token" with it and getting an access token.
I also tried resending the code_challenge in case the code_challenge_method is set to plain. But it failed with the same error.
MSAL.PS Version:
Script 4.37.0.0 MSAL.PS
Hi, I've tried to reproduce your issue but before going exactly your scenario where you try to generate an access toekn for a confidential app, I've started with a public one. Here what I've done: New app registration, V2 endpoint enforced, allow public client true, redirecturi localhost, no secret.
Then I've started Fiddler and run in the Pwsh console:
Get-MsalToken -ClientId $clientId -TenantId $TenantId -RedirectUri $RedirectURI -Scopes $scopes -ForceRefresh
On Fiddler side, we can see the command executed is:
https://login.microsoftonline.com/<tenantId>/oauth2/v2.0/authorize?scope=openid+offline_access+User.Read &response_type=code &client_id=<clientId> &redirect_uri=http%3A%2F%2Flocalhost%2F &client-request-id=8b1fcba1-725a-415c-b761-b61c4fff3795 &x-client-SKU=MSAL.NetCore &x-client-Ver=4.37.0.0 &x-client-CPU=x64 &x-client-OS=Microsoft+Windows+10.0.19042 &prompt=select_account &code_challenge=XRu4k8rduOKHB....kxWd8vI6s4rgjU &code_challenge_method=S256 &state=e837e472-4f90-403d-9c2f-bfb360ee82632ebb39b3-72a5-4488-9632-b8f9964b8ae4 &client_info=1 HTTP/1.1
As you can see, auth code flow with PKCE (code_challenge_method=S256) seems to be the default behavior.
I will continue my investigation
After a little bit of reverse engineering, I have to admit this is not obvious. But to be honest, trying to do a confidential app (because now you have a secret) from a PS console does not make any sense, or I don't understand the use case :p. You should use the publicclientapp (see above) in this case. Anyway here what I've done to make it work:
Create a new app, V2 endpoint, kept the allow public client at false this time, native client redirect uri with localhost and of course a secret.
Now to get a token, you can do:
$clientId = "02b3de1e-0047-4d53-9a9e-a58932800003" $TenantId = "<tenantId>" $RedirectURI = "http://localhost" $ExtraQueryParameters = @{} $ExtraQueryParameters.Add('client_secret','<your secret in cleartext>') $tokenInfo = Get-MsalToken -Interactive -ClientId $clientId -TenantId $TenantId -RedirectUri $RedirectURI -ExtraQueryParameters $ExtraQueryParameters
And that's it, you should now get your Id/access/refresh token.
But again, if you plan to use this semi-interractive (because of Refresh token) flow, I think using 2 apps, one public (your Pwsh console) which call your backend (second app) should be a better option.
BTW, this is what I get from Fiddler:
I hope it will help you. Cheers
Thx for looking into this. I can see from your Fiddler trace what I'm expecting and trying to achieve. However, I'm not progressing successfully.
In your last example you show getting a token without specifying PKCE yet your Fiddler trace shows the code_challenge. I've tried adding in the code_challenge to $ExtraQueryParameters but Get-MsalToken fails with
Get-MsalToken:
Line |
14 | $tokenInfo = Get-MsalToken -Interactive `
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Duplicate query parameter 'code_challenge' in extraQueryParameters.
How did you send code_challenge in the authcode request?
Nothing in my sleeves :p. It seems to be the default behavior. Here what I've done:
Again, my app registration is a confidential one, and redirect URI set as a native client. Sonce the last post, I've changed the redirecturi from localhost to msal.. just for testing.
Now here the 2 interresting calls. The first one with the code response_type:
And the back channel one with the verifier:
So as you can see, I don't need any custom code, the MSAL lib seems to manage everything on his own.
Once you get the token, you can use the -silent insted of the -interrctive instead to use the cache.
That makes sense if the MSAL.PS doing it by default. It explains the duplicate entries for values when I was adding them via Extra Parameters. Thanks for your help, much appreciated.
Yeah, MSAL.net always uses PKCE with auth code flow. https://docs.microsoft.com/en-us/azure/active-directory/develop/sample-v2-code
That makes sense if the MSAL.PS doing it by default. It explains the duplicate entries for values when I was adding them via Extra Parameters. Thanks for your help, much appreciated.
Hi Darren,
I'm also trying to leverage MSAL.PS to emulate a confidential client with the auth code flow. However, MSAL.PS seems to be wrapping the client_secret parameter in the query string while it is actually expected in the body. Thus the token endpoint always responses with "The request body must contain the following parameter: 'client_assertion' or 'client_secret'."
Have you managed to get through this?
Thanks.
I'm trying to use MSAL.PS for an Authorization code with PKCE Flow. PKCE was introduced in MSAL.NET with MSAL 4.30.0 .
Intended Process: Initiate an interactive AuthN with PKCE parameters to get an Authorisation Code to then use to get an Access Token.
Error:
Example to repo:
Alternate: Introduce another option with MSAL.PS to support the Authorization code with PKCE Flow.