获得网站访问令牌与Azure的AD集成B2C

问题描述 投票:2回答:3

我有一个ASP.NET MVC 2.2核心应用,与湛蓝的AD B2C对用户进行认证集成。我能正确登录,用户进行身份验证。

我还创建了一个ASP.NET核心网页API,还与Azure的B2C AD整合,目标是调用网页API从ASP.NET MVC控制器的操作方法。

所以我添加的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 2.2的核心),那么我必须要通过一个IAccount,所以我需要调用GetAccountsAsync(),这不返回帐户。

asp.net-mvc azure asp.net-core azure-ad-b2c
3个回答
1
投票

.NETCore B2C web app已更新为使用MSAL V2.7。正在使用的范围是不正确的,所以现在的样本使用了正确的范围,并返回一个访问令牌。

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


1
投票

首先,你需要问你需要访问您的API时调用AcquireTokenSilentAsync的范围

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

而你需要实现初始令牌获取和使用授权中间件AuthorizationCodeReceived通知,MSAL令牌缓存保存令牌:

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核心2.0和MSAL 2的代码示例,请阅读详细的解释README.md

您也可以点击here为对Azure的AD B2C用户进行身份验证,取得使用MSAL.NET使用ASP.NET 2.1内核的访问令牌代码示例。


0
投票

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

话说,在运行它时,我得到一个未经授权的错误。所以,真的不知道这是怎么回事这一点。但我得到一个帐户回来。

© www.soinside.com 2019 - 2024. All rights reserved.