主要目标是在 OIDC 用户具有类型为“BlockedFrom”的自定义声明(在 ClaimsTransformation 中添加)时阻止访问门户。
我已经通过Startup.Configure方法中的中间件解决了它。一般原因是保留原始请求 URL 而不重定向到 /Account/AccessDenied 页面。
app.Use((context, next) =>
{
var user = context.User;
if (user.IsAuthenticated())
{
// Do not rewrite path when it marked with custom [AllowBlockedAttribute]!
// /Home/Logout, for example. But how?
//
if (user.HasClaim(x => x.Type == UserClaimTypes.BlockedFrom))
{
// Rewrite to run specific method of HomeController for blocked users
// with detailed message.
//
context.Request.Path = GenericPaths.Blocked;
}
}
return next();
});
但是有一个意想不到的结果:Logout方法也HomeController被阻塞了。用户被阻止时无法注销,哈哈!想到的第一件事 - 检查自定义属性,例如[AllowBlockedAttribute]. 中间件中的硬编码路径常量看起来很疯狂。如何访问中间件中调用方法的属性?
另一种(更优雅)的方法是将此逻辑自定义BlockedHandler : AuthorizationHandler<BlockedRequirement>并在Startup.ConfigureServices方法的MVC 选项中将其分配为一般策略:
services.AddSingleton<IAuthorizationHandler, BlockedHandler>();
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddRequirements(new BlockedRequirement())
.Build();
// Set the default authentication policy to require users to be authenticated.
//
options.Filters.Add(new AuthorizeFilter(policy));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
假设实现BlockedHandler:
public class BlockedHandler : AuthorizationHandler<BlockedRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, BlockedRequirement requirement)
{
if (!context.User.HasClaim(c => c.Type == UserClaimTypes.BlockedFrom))
{
context.Succeed(requirement);
return Task.CompletedTask;
}
白衣染霜花
斯蒂芬大帝