下面的代码检查控制器中所有操作方法的Authorization。我用的是Asp。Core 2.2
<<p>授权属性/strong>public class AuthorizeRolesAttribute : AuthorizeAttribute
{
public AuthorizeRolesAttribute(params string[] roles) : base()
{
Roles = string.Join(",", roles);
}
}
控制器
[AuthorizeRoles(Roles.Worker,Roles.Contractor)]
public class MyController:Controller
{
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Action1()
{
return View();
}
[HttpPost]
public ActionResult Action2()
{
return View();
}
}
我想在应用特定属性时跳过对Index
操作方法的授权。与[AllowAnonymous]
属性的工作方式相同。然而,我认为[AllowAnonymous]
将允许未经认证的用户。我不希望未经身份验证的用户访问索引。我还试图避免在单个操作方法上应用Authorize属性。
所以controller应该是
[AuthorizeRoles(Roles.Worker,Roles.Contractor)]
public class MyController:Controller
{
[IgnoreAthorization]
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Action1()
{
return View();
}
[HttpPost]
public ActionResult Action2()
{
return View();
}
}
更新1
当操作用[IgnoreAuthorization]
属性装饰时,策略构建器中是否有方法根据授权跳过角色?以下是我目前的创业策略。我使用OpenID Connect进行身份验证
var authorizationPolicy = new AuthorizationPolicyBuilder()
.RequireClaim(ClaimTypes.Email)
.RequireClaim(ClaimTypes.NameIdentifier)
.RequireClaim(ClaimTypes.Name)
.RequireClaim(IdentityClaimTypes.IdToken)
.RequireAuthenticatedUser()
.Build();
// mvc
services.AddMvc(options =>
{
options.Filters.Add(new AuthorizeFilter(authorizationPolicy));
})
更新2
尝试添加自定义AuthorizeFilter但不工作
public class MyAuthorizeFilter : AuthorizeFilter
{
public MyAuthorizeFilter(AuthorizationPolicy policy)
: base(policy)
{
}
public override Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
var skip = context.ActionDescriptor.EndpointMetadata.Any(x => x is IgnoreAthorization) &&
context.HttpContext.User.Identity.IsAuthenticated;
if (skip)
{
return Task.CompletedTask;
}
return base.OnAuthorizationAsync(context);
}
}
然后在startup.cs中添加MyAuthorizeFilter
// mvc
services.AddMvc(options =>
{
options.Filters.Add(new MyAuthorizeFilter(authorizationPolicy));
})
对于多策略评估,如果您将多个策略应用于控制器或操作,则所有策略必须在授予访问权限之前通过。
在您的场景中,您希望经过身份验证的用户访问Index页,而基于role的用户访问其他操作。如果你将策略设置为控制器,然后在action方法上使用另一个策略,它将首先检查controller的策略,然后再检查action的策略。
因此,根据您的场景,唯一的方法是设置至少两个策略,一个用于Authenticated User,另一个用于基于角色的用户。然后,按如下方式应用策略:
public class MyController:Controller
{
[Authorize(policy: "EveryOne")]
public ... Index(){
}
[HttpPost]
[Authorize(policy: "Role")]
public ActionResult Action1()
{
return View();
}
[HttpPost]
[Authorize(policy: "Role")]
public ActionResult Action2()
{
return View();
}
}
更多详细信息,请参考以下文章:
多重政策评估
授权属性应该有一个标志来覆盖之前的授权属性控制器-方法