当我不尝试使用隐式流时,Azure AD B2C 错误 AADB2C90057
Azure AD B2C error AADB2C90057 when I am NOT trying to use the implicit flow
我正在使用 ASP.NET Core 3.1 和 Azure AD B2C。我的目标是将 Authorization Code Flow 用于我的整个网络应用程序,但文档并不直接。
我按照此处给出的说明进行操作:Web app that signs in users: Code configuration
然而,当我尝试访问我的网站时,出现以下错误:
[ERR] Message contains error: '"unauthorized_client"', error_description: '"AADB2C90057: The provided application is not configured to allow the 'OAuth' Implicit flow. uri: '"error_uri is null"'. (95c3107f)
在我的应用程序注册中,我没有启用隐式授权的两个选项中的任何一个(访问令牌和 ID 令牌)。
同样,我的目标是在任何地方都使用授权代码流。
知道为什么我收到消息说我的应用程序应该配置为允许隐式流吗?我应该如何配置它以使用授权代码流?
如果您想安全地将用户登录到 Web 应用程序,我们应该使用 OpenId Connect 协议。 response_type 需要包含 id_token
。所以我们需要启用Implicit Grant
。详情请参考document and the document
关于如何在.net core web app中实现OpenId connect,我们可以使用sdk Microsoft.AspNetCore.Authentication.AzureADB2C.UI
。详细步骤如下
在 Web 应用程序中实施 Azure AD B2C 身份验证
一个。在 appsettings.json
中添加以下设置
{
"AzureAdB2C": {
"Instance": "https://<your-tenant-name>.b2clogin.com",
"ClientId": "<web-app-application-id>",
"Domain": "<your-b2c-domain>"
"CallbackPath": "/signin-oidc",
"SignUpSignInPolicyId": "B2C_1_test",
"ResetPasswordPolicyId": "B2C_1_test2",
"EditProfilePolicyId": "B2C_1_test1"
},
...
}
b。在Startup.cs
中添加如下代码
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
.AddAzureADB2C(options => Configuration.Bind("AzureAdB2C", options));
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
}
c。实现登录和退出。 sdk 已经帮我们实现了登录和退出的方法。所以我们可以直接使用它。例如
我的login.cshtml
@using System.Security.Principal
@using Microsoft.AspNetCore.Authentication.AzureADB2C.UI
@using Microsoft.Extensions.Options
@inject IOptionsMonitor<AzureADB2COptions> AzureADB2COptions
@{
var options = AzureADB2COptions.Get(AzureADB2CDefaults.AuthenticationScheme);
}
<ul class="navbar-nav">
@if (User.Identity.IsAuthenticated)
{
<li class="nav-item">
<span class="nav-text text-dark">Hello @User.Identity.Name!</span>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="AzureADB2C" asp-controller="Account" asp-action="SignOut">Sign out</a>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="AzureADB2C" asp-controller="Account" asp-action="SignIn">Sign in</a>
</li>
}
</ul>
测试
更新
如果您想使用授权代码流程,请更改 startup.cs
代码如下。
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
.AddAzureADB2C(options => Configuration.Bind("AzureAdB2C", options));
services.Configure<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme, options =>
{
options.UsePkce = false;
options.ResponseType = "code";
options.Scope.Add("offline_access");
options.Events = new OpenIdConnectEvents()
{
OnAuthorizationCodeReceived = async context => {
var code = context.ProtocolMessage.Code;
var request = context.HttpContext.Request;
string currentUri = UriHelper.BuildAbsolute(
request.Scheme,
request.Host,
request.PathBase,
options.CallbackPath);
IConfidentialClientApplication cca = ConfidentialClientApplicationBuilder.Create(options.ClientId)
.WithB2CAuthority(options.Authority)
.WithRedirectUri(currentUri)
.WithClientSecret(options.ClientSecret)
.Build();
try
{
AuthenticationResult result = await cca.AcquireTokenByAuthorizationCode(options.Scope, code)
.ExecuteAsync();
context.HandleCodeRedemption(result.AccessToken, result.IdToken);
}
catch (Exception ex)
{
//TODO: Handle
throw;
}
}
};
});
services.AddRazorPages();
}
之后
services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme).AddAzureADB2C( ....
只需添加
services.Configure<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme, options =>
{
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Add(options.ClientId);
});
我正在使用 ASP.NET Core 3.1 和 Azure AD B2C。我的目标是将 Authorization Code Flow 用于我的整个网络应用程序,但文档并不直接。
我按照此处给出的说明进行操作:Web app that signs in users: Code configuration
然而,当我尝试访问我的网站时,出现以下错误:
[ERR] Message contains error: '"unauthorized_client"', error_description: '"AADB2C90057: The provided application is not configured to allow the 'OAuth' Implicit flow. uri: '"error_uri is null"'. (95c3107f)
在我的应用程序注册中,我没有启用隐式授权的两个选项中的任何一个(访问令牌和 ID 令牌)。
同样,我的目标是在任何地方都使用授权代码流。
知道为什么我收到消息说我的应用程序应该配置为允许隐式流吗?我应该如何配置它以使用授权代码流?
如果您想安全地将用户登录到 Web 应用程序,我们应该使用 OpenId Connect 协议。 response_type 需要包含 id_token
。所以我们需要启用Implicit Grant
。详情请参考document and the document
关于如何在.net core web app中实现OpenId connect,我们可以使用sdk Microsoft.AspNetCore.Authentication.AzureADB2C.UI
。详细步骤如下
在 Web 应用程序中实施 Azure AD B2C 身份验证
一个。在 appsettings.json
中添加以下设置{ "AzureAdB2C": { "Instance": "https://<your-tenant-name>.b2clogin.com", "ClientId": "<web-app-application-id>", "Domain": "<your-b2c-domain>" "CallbackPath": "/signin-oidc", "SignUpSignInPolicyId": "B2C_1_test", "ResetPasswordPolicyId": "B2C_1_test2", "EditProfilePolicyId": "B2C_1_test1" }, ... }
b。在Startup.cs
中添加如下代码public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme) .AddAzureADB2C(options => Configuration.Bind("AzureAdB2C", options)); services.AddRazorPages(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapControllers(); }); }
c。实现登录和退出。 sdk 已经帮我们实现了登录和退出的方法。所以我们可以直接使用它。例如
我的login.cshtml
@using System.Security.Principal @using Microsoft.AspNetCore.Authentication.AzureADB2C.UI @using Microsoft.Extensions.Options @inject IOptionsMonitor<AzureADB2COptions> AzureADB2COptions @{ var options = AzureADB2COptions.Get(AzureADB2CDefaults.AuthenticationScheme); } <ul class="navbar-nav"> @if (User.Identity.IsAuthenticated) { <li class="nav-item"> <span class="nav-text text-dark">Hello @User.Identity.Name!</span> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="AzureADB2C" asp-controller="Account" asp-action="SignOut">Sign out</a> </li> } else { <li class="nav-item"> <a class="nav-link text-dark" asp-area="AzureADB2C" asp-controller="Account" asp-action="SignIn">Sign in</a> </li> } </ul>
测试
更新
如果您想使用授权代码流程,请更改 startup.cs
代码如下。
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
.AddAzureADB2C(options => Configuration.Bind("AzureAdB2C", options));
services.Configure<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme, options =>
{
options.UsePkce = false;
options.ResponseType = "code";
options.Scope.Add("offline_access");
options.Events = new OpenIdConnectEvents()
{
OnAuthorizationCodeReceived = async context => {
var code = context.ProtocolMessage.Code;
var request = context.HttpContext.Request;
string currentUri = UriHelper.BuildAbsolute(
request.Scheme,
request.Host,
request.PathBase,
options.CallbackPath);
IConfidentialClientApplication cca = ConfidentialClientApplicationBuilder.Create(options.ClientId)
.WithB2CAuthority(options.Authority)
.WithRedirectUri(currentUri)
.WithClientSecret(options.ClientSecret)
.Build();
try
{
AuthenticationResult result = await cca.AcquireTokenByAuthorizationCode(options.Scope, code)
.ExecuteAsync();
context.HandleCodeRedemption(result.AccessToken, result.IdToken);
}
catch (Exception ex)
{
//TODO: Handle
throw;
}
}
};
});
services.AddRazorPages();
}
之后 services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme).AddAzureADB2C( ....
只需添加
services.Configure<OpenIdConnectOptions>(AzureADB2CDefaults.OpenIdScheme, options =>
{
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Add(options.ClientId);
});