我有一个 ASP.NET Core MVC 应用程序,我想根据当前存储在数据库中的用户属性使用 2 个不同的 Azure B2C 身份验证策略。以客户与代理的不同要求为例进行思考。
我知道我可以通过配置绑定(bind)单个策略,但是有没有办法在运行时动态选择策略?
最佳答案
是的,假设您使用的是 Microsoft.Identity.Web,那么您的登录链接不会转到 /MicrosoftIdentity/Account/SignIn
,而是转到您创建的将填充的自定义操作您要使用的策略名称,例如 /Account/SignIn
:
[AllowAnonymous]
public class AccountController : Controller
{
public IActionResult SignIn(string? policy)
{
var properties = new AuthenticationProperties
{
RedirectUri = this.Url.Content("~/"),
};
// in this example we're allowing the policy name to be passed in as a parameter to the action, but this would be replaced by your custom policy selection logic
if (!string.IsNullOrWhiteSpace(policy))
{
properties.Items["policy"] = policy;
// HACK: Microsoft.Identity.Web removes the policy item as part of the redirect to IdP but we need to update the token URL when using code flow, so fix that...
properties.Items["customPolicy"] = policy;
}
return this.Challenge(properties, OpenIdConnectDefaults.AuthenticationScheme);
}
}
通过填充 AuthenticationProperties.Items["policy"]
,Microsoft.Identity.Web 在重定向到 B2C /authorize
终结点时将自动使用该策略名称。但是,如果您使用 OpenID Connect code
流程(您应该如此),则需要确保 /token
端点也使用正确的策略。
Microsoft.Identity.Web 在 /authorize
调用后删除 policy
项,因此上面的示例还将策略名称设置为 customPolicy
所以当需要交换代币时它就可用。只需更新 Startup.cs
中的 Microsoft.Identity.Web 配置即可处理 OnAuthorizationCodeReceived
事件:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(opt =>
{
// other setup here...
opt.Events.OnAuthorizationCodeReceived += ctx =>
{
if (ctx.Properties?.Items.TryGetValue("customPolicy", out var customPolicy) == true)
{
ctx.TokenEndpointRequest.TokenEndpoint = $"{opt.Instance}/{opt.Domain}/{customPolicy}/oauth2/v2.0/token";
}
return Task.CompletedTask;
};
}/* cookie config happens here if you're overriding defaults */);
如果您希望此功能与 [Authorize]
一起正常工作,那么您还需要更改默认身份验证方案,以便它检查您的 Cookie 并更新 Cookie 配置以使用您的自定义登录 URL默认 Microsoft.Identity.Web 之一:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(opt =>
{
// other setup here...
opt.Events.OnAuthorizationCodeReceived += ctx =>
{
if (ctx.Properties?.Items.TryGetValue("customPolicy", out var customPolicy) == true)
{
ctx.TokenEndpointRequest.TokenEndpoint = $"{opt.Instance}/{opt.Domain}/{customPolicy}/oauth2/v2.0/token";
}
return Task.CompletedTask;
};
},
opt =>
{
// this should be the actual URL, not just the controller and action name
opt.LoginPath = "/Account/SignIn";
opt.Cookie.SameSite = SameSiteMode.None;
opt.Cookie.SecurePolicy = CookieSecurePolicy.Always;
opt.Cookie.IsEssential = true;
});
关于azure - 我可以将 ASP.NET Core 登录路由到不同的 Azure B2C 策略吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76802787/