在asp.net Core中使用MSAL 1.1.0-preview无法通过授权代码获取AccessToken [英] Failed to get AccessToken via authorization code using MSAL 1.1.0-preview in asp.net core

查看:159
本文介绍了在asp.net Core中使用MSAL 1.1.0-preview无法通过授权代码获取AccessToken的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我按照以下官方步骤尝试了方案" Asp.Net核心.我正在使用AuthorizationCode获取访问令牌,但是它始终返回id令牌和 NULL访问令牌.

I followed official steps as below to try the scenario "web app calling a Web API in Azure Ad B2C", the only difference is I am using Asp.Net core. I am using AuthorizationCode to get the access token, but it always returns with id token and NULL access token.

  • Create an Azure AD B2C tenant.
  • Register a web api.
  • Register a web app.
  • Set up policies.
  • Grant the web app permissions to use the web api.

我的代码:

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
    AuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme,
    AutomaticChallenge = true,
    ClientId = aadB2cSettings.ClientId,
    MetadataAddress = $"{aadB2cSettings.Instance}{aadB2cSettings.Tenant}/v2.0/.well-known/openid-configuration?p={aadB2cSettings.B2cSignUpOrSignInPolicy}",
    PostLogoutRedirectUri = aadB2cSettings.RedirectUrl,

    ResponseType = OpenIdConnectResponseType.CodeIdToken,
    TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = "name"
    },

    Events = new OpenIdConnectEvents
    {
        OnAuthorizationCodeReceived = async context =>
        {
            var authCode = context.TokenEndpointRequest.Code;
            var b2cAuthority = $"{aadB2cSettings.Instance}tfp/{aadB2cSettings.Tenant}/{aadB2cSettings.B2cSignUpOrSignInPolicy}/v2.0/.well-known/openid-configuration";
            var cca = new ConfidentialClientApplication(
                aadB2cSettings.ClientId, 
                b2cAuthority,
                aadB2cSettings.RedirectUrl, 
                new ClientCredential(aadB2cSettings.ClientSecret), 
                new TokenCache(), 
                null);

            try
            {
                var authResult = await cca.AcquireTokenByAuthorizationCodeAsync(authCode, new[] { "https://hulab2c.onmicrosoft.com/b2cdemo/all" });
                context.HandleCodeRedemption(authResult.AccessToken, authResult.IdToken);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    },

使用提琴手来捕获请求,它是:

Used fiddler to capture the request, it is:

开机自检 https://login.microsoftonline.com/hulab2c.onmicrosoft.com/oauth2/v2.0/token?p=b2c_1_signuporsignin HTTP/1.1

POST https://login.microsoftonline.com/hulab2c.onmicrosoft.com/oauth2/v2.0/token?p=b2c_1_signuporsignin HTTP/1.1

请求正文:

client_id = 1ff91f47-08ee-4973-83f4-379ad7e0679c& client_info = 1& client_secret = ......& scope = https%3A%2F%2Fhulab2c.onmicrosoft.com%2Fb2cdemo%2Fall + offline_access + openid + profile& grant_type = authorization_code& code = ......& redirect_uri = https%3A%2F%2Flocalhost%3A44383%2F

client_id=1ff91f47-08ee-4973-83f4-379ad7e0679c&client_info=1&client_secret=......&scope=https%3A%2F%2Fhulab2c.onmicrosoft.com%2Fb2cdemo%2Fall+offline_access+openid+profile&grant_type=authorization_code&code=......&redirect_uri=https%3A%2F%2Flocalhost%3A44383%2F

返回:

{"id_token":"......","token_type":承载者","not_before":1494494423,"client_info":"......","scope":" }

{"id_token":"......","token_type":"Bearer","not_before":1494494423,"client_info":"......","scope":""}

因此只有ID令牌,没有访问令牌.但是我们应该在这里获取访问令牌,对吧?

So only id token, no access token. But we should get access token here, right?

推荐答案

最后发现我的失败原因:获取AuthorizationCode的请求不包含目标范围.在代码中反映出来,对于aspnetcore中的OpenIdConnectOption,Scope参数为只读,其默认值为打开的配置文件". 在OpenIdConnectOption中范围是只读的

Finally found out my failure reason: the request to get AuthorizationCode doesn't contain the target scope. Reflect in code, for OpenIdConnectOption in aspnetcore, the Scope parameter is readonly and its default value is "opened profile". Scope is readonly in OpenIdConnectOption

因此,发送的默认授权码请求为:

So the default authorization code request sent is:

获取 ://login.microsoftonline.com/hulab2c.onmicrosoft .com/oauth2/v2.0/authorize?p = b2c_1_signuporsignin& client_id = 7f865ca0-271e-4f27-be21-6f0072fe3ad7& redirect_uri = https%3A%2F%2Flocalhost%3A44355%2Fsignin-oidc& response_type = code%20 = openid%20profile& response_mode = form_post& nonce = ...... HTTP/1.1

GET https://login.microsoftonline.com/hulab2c.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1_signuporsignin&client_id=7f865ca0-271e-4f27-be21-6f0072fe3ad7&redirect_uri=https%3A%2F%2Flocalhost%3A44355%2Fsignin-oidc&response_type=code%20id_token&scope=openid%20profile&response_mode=form_post&nonce=...... HTTP/1.1

因此,使用此授权码作为响应来获取令牌,即使我们在令牌请求中设置了正确的作用域,我们仍然无法获取访问码,而只能获取id令牌,因为提供授权码仅适用于"openid个人资料" .

Thus, using this authorization code in response to get token, even we set right scope in the token request, we still can't get the access code but only id token, because the provide authorization code is only for "openid profile".

要解决此问题,我们还需要将目标Web API范围也添加到授权代码中.这是解决方法的代码:

To fix this, we need to add target web api scope into the authorization code as well. Here is the how-to-fix code:

Events = new OpenIdConnectEvents
{
       OnRedirectToIdentityProvider = context =>
       {
            context.ProtocolMessage.Scope += $" offline_access {myapiscope}";

            return Task.FromResult(0);
       },
       ......
}

在AspNet中,我们不需要这样做,因为它的作用域不是aspnetcore只读的,可以直接设置:

In AspNet, we don't need to do this because its scope is not readonly as aspnetcore and can be set directly:

new OpenIdConnectAuthenticationOptions
{
      ......
      Scope = $"openid profile offline_access {ReadTasksScope} {WriteTasksScope}"
}

这篇关于在asp.net Core中使用MSAL 1.1.0-preview无法通过授权代码获取AccessToken的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆