代码之家  ›  专栏  ›  技术社区  ›  L-Four

在与Azure AD B2C集成的网站中获取访问令牌

  •  2
  • L-Four  · 技术社区  · 6 年前

    我有一个ASP.NET MVC Core 2.2应用程序,它与一个Azure AD B2C集成以对用户进行身份验证。我可以正确登录,并且用户已经过身份验证。

    我还创建了一个ASP.NET核心Web API,它也与Azure B2C AD集成,目标是从ASP.NET MVC控制器操作方法调用该Web API。

    因此,我在MVC站点的控制器中添加了以下测试代码:

    if (HttpContext.User.Identity.IsAuthenticated)
    {
        string signedInUserID = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
        TokenCache userTokenCache = new MSALSessionCache(signedInUserID, HttpContext).GetMsalCacheInstance();
        ConfidentialClientApplication cca = new ConfidentialClientApplication(mgpPortalApplicationId, authority, redirectUri, new ClientCredential(mgpPortalSecretKey), userTokenCache, null);                
        IEnumerable<IAccount> accounts = await cca.GetAccountsAsync();
        IAccount firstAccount = accounts.FirstOrDefault();
        AuthenticationResult result = await cca.AcquireTokenSilentAsync(null, firstAccount, authority, false);
        HttpClient client = new HttpClient();
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:44307/api/values");
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
        HttpResponseMessage response = await client.SendAsync(request);
    }
    

    问题是 accounts.FirstOrDefault() 返回空值。不知道为什么:

    有人知道我做错了什么吗?谢谢你的提示!

    附加观察: 如果我运行演示 https://github.com/Azure-Samples/active-directory-b2c-dotnetcore-webapp ,它使用旧的microsoft.identity.client,然后对cca.users.firstOrDefault()的调用会正确地返回用户。但是,当我将此演示项目升级到Microsoft.Identity.Client 2.7(对于.NET Core 2.2是必需的)时,我必须传递一个IAccount,因此我需要调用 GetAccountsAsync() ,这个返回 帐户。

    3 回复  |  直到 6 年前
        1
  •  0
  •   Jenny    6 年前

    这个 .NETCore B2C web app 已更新为使用MSAL v2.7。使用的作用域不正确,因此示例现在使用正确的作用域,并返回访问令牌。

    "ApiScopes": "https://fabrikamb2c.onmicrosoft.com/helloapi/demo.read"

        2
  •  0
  •   Nan Yu    6 年前

    首先,当调用AcquireTokensilentAsync时,需要请求访问API所需的范围。

    AuthenticationResult result = await cca.AcquireTokenSilentAsync(scope, cca.Users.FirstOrDefault(), AzureAdB2COptions.Authority, false);
    

    您需要实现初始令牌获取,并使用 AuthorizationCodeReceived 授权中间件通知:

    public async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
    {
        // Use MSAL to swap the code for an access token
        // Extract the code from the response notification
        var code = context.ProtocolMessage.Code;
    
        string signedInUserID = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value;
        TokenCache userTokenCache = new MSALSessionCache(signedInUserID, context.HttpContext).GetMsalCacheInstance();
        ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);
        try
        {
            AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, AzureAdB2COptions.ApiScopes.Split(' '));
    
    
            context.HandleCodeRedemption(result.AccessToken, result.IdToken);
        }
        catch (Exception ex)
        {
            //TODO: Handle
            throw;
        }
    }
    

    因此,当在控制器中获取令牌时,MSAL将查找缓存并返回任何符合要求的缓存令牌。如果此类访问令牌已过期或不存在合适的访问令牌,但存在关联的刷新令牌,MSAL将自动使用该令牌获取新的访问令牌并透明地返回:

    // Retrieve the token with the specified scopes
    var scope = AzureAdB2COptions.ApiScopes.Split(' ');
    string signedInUserID = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
    TokenCache userTokenCache = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance();
    ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);
    
    AuthenticationResult result = await cca.AcquireTokenSilentAsync(scope, cca.Users.FirstOrDefault(), AzureAdB2COptions.Authority, false);
    

    Here 是使用ASP.NET Core 2.0和MSAL 2的代码示例,请阅读 README.md 详细解释。

    您也可以单击 here 用于验证用户对Azure AD B2C的身份并使用ASP.NET Core 2.1使用MSAL.NET获取访问令牌的代码示例。

        3
  •  0
  •   zawisza    6 年前

    @L-4,您提到的代码实际上有一个分支已经更新到MSAL的最新版本: active-directory-b2c-dotnetcore-webapp

    这么说,当运行它时,我会得到一个未经授权的错误。所以不太确定是怎么回事。但我确实有一个账户。