我使用Visual Studio最新的 New Project 向导创建了一个ASP Core 2.0网页(Razor Pages),它使用个人帐户作为我的身份验证选项。我创建了一个Azure AD B2C租户并验证它是否正常工作。
当我运行向导创建的Web应用程序并单击右上角的登录时,它会重定向到我的Azure AD B2C站点,我可以正常登录。
登录后,回调网址将转到我的用户机密中配置的端点:
...
"CallbackPath": "/signin-oidc",
...
这一切似乎都能正常运作。我了解Azure AD B2C门户将令牌发送回上述/signin-oidc
回调路径并存储它。
如何检索该令牌的值?
我一直在关注所有Azure AD B2C指南,但并非所有指南都已更新到ASP Core 2.0,并且它们似乎都没有使用15.4 VS向导生成的代码:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAdB2C(options => Configuration.Bind("AzureAdB2C", options))
.AddCookie();
services.AddMvc();
}
注意:.AddAzureAdB2C(...)
没有一个B2C样本正在使用它,所以我很难遵循。
我的最终目标是获取令牌并将其用于我使用Autorest从Swagger生成的强类型API类中,这些API类需要令牌。
答案 0 :(得分:2)
Azure AD B2C .Net Core示例中概述了执行此操作的最佳方法,特别是branch for Core 2.0。
在普通模型/流程中,您的应用程序将获得id_token和授权代码,但不会获得令牌。您的中间层需要交换授权代码。您可以将此令牌发送到您的网络API。
执行此操作的方法包括以下内容:
public Task OnRedirectToIdentityProvider(RedirectContext context)
{
var defaultPolicy = AzureAdB2COptions.DefaultPolicy;
if (context.Properties.Items.TryGetValue(AzureAdB2COptions.PolicyAuthenticationProperty, out var policy) &&
!policy.Equals(defaultPolicy))
{
context.ProtocolMessage.Scope = OpenIdConnectScope.OpenIdProfile;
context.ProtocolMessage.ResponseType = OpenIdConnectResponseType.IdToken;
context.ProtocolMessage.IssuerAddress = context.ProtocolMessage.IssuerAddress.ToLower().Replace(defaultPolicy.ToLower(), policy.ToLower());
context.Properties.Items.Remove(AzureAdB2COptions.PolicyAuthenticationProperty);
}
else if (!string.IsNullOrEmpty(AzureAdB2COptions.ApiUrl))
{
context.ProtocolMessage.Scope += $" offline_access {AzureAdB2COptions.ApiScopes}";
// -----------------------------
// THIS IS THE IMPORTANT PART:
context.ProtocolMessage.ResponseType = OpenIdConnectResponseType.CodeIdToken;
// -----------------------------
}
return Task.FromResult(0);
}
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;
}
}
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);
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, AzureAdB2COptions.ApiUrl);
// Add token to the Authorization header and make the request
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
HttpResponseMessage response = await client.SendAsync(request);
答案 1 :(得分:1)
ASP.NET核心团队在此过程中创建了2个优秀文档。
使用Visual Studio创建配置为使用Azure AD B2C租户进行身份验证的ASP.NET Core Web应用程序
使用Visual Studio创建配置为使用Azure AD B2C租户进行身份验证的Web API