【问题标题】:Failed to get AccessToken via authorization code using MSAL 1.1.0-preview in asp.net core在 asp.net 核心中使用 MSAL 1.1.0-preview 无法通过授权代码获取 AccessToken
【发布时间】:2017-05-15 02:13:33
【问题描述】:

我按照以下官方步骤尝试了“web app calling a Web API in Azure Ad B2C”场景,唯一的区别是我使用的是Asp.Net core。我正在使用 AuthorizationCode 获取访问令牌,但它总是返回 id 令牌和 NULL 访问令牌

我的代码:

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;
            }
        }
    },

使用 fiddler 来捕获请求,它是:

发布 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

返回:

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

所以只有 id 令牌,没有访问令牌。但是我们应该在这里获取访问令牌,对吧?

【问题讨论】:

    标签: azure-ad-b2c


    【解决方案1】:

    终于找到了我失败的原因:获取AuthorizationCode的请求不包含目标范围。体现在代码中,对于aspnetcore中的OpenIdConnectOption,Scope参数是只读的,其默认值为“opened profile”。 Scope is readonly in OpenIdConnectOption

    所以发送的默认授权码请求是:

    获取 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 profile ”。

    要解决这个问题,我们还需要将目标 web api 范围添加到授权代码中。以下是修复方法代码:

    Events = new OpenIdConnectEvents
    {
           OnRedirectToIdentityProvider = context =>
           {
                context.ProtocolMessage.Scope += $" offline_access {myapiscope}";
    
                return Task.FromResult(0);
           },
           ......
    }
    

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

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

    【讨论】:

    • 有点晚了,你就不能options.Scope.Add("myscope");吗?我的意思是 ICollection<T> 有一个 Add 方法。
    【解决方案2】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-28
      • 1970-01-01
      • 1970-01-01
      • 2018-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      相关资源
      最近更新 更多