如何在 ASP.NET Core 2.0 中使用基于视图的授权
How to use View Based Authorization in ASP.NET Core 2.0
我的 ASP.NET Core 2.0 Web 应用程序出现奇怪的行为,授权在控制器级别通过,但在视图级别失败。
这是 ASP.NET Core 2.0 中的错误还是我的代码有问题?
//Controller中授权成功
信息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1]
用户授权成功:(用户名)。
//进入控制器
信息:Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
使用参数 ((null) 执行操作方法 HomeController.Index (Bams)
) - 模型状态有效
...
//视图失败
信息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
用户授权失败:(用户名)。
在 Startup.cs 中配置服务:
services.AddAuthorization(options => {
options.AddPolicy("HasName", policy => policy.Requirements.Add(new HasNameRequirement()));
});
HomeController.cs:
[Authorize(Policy="HasName")]
public class HomeController : Controller
{
public IActionResult Index(){
return View();
}
}
有名称要求:
public class HasNameRequirement : IAuthorizationRequirement {
public HasNameRequirement() { }
}
HasNameHandler:
public class HasNameHandler : AuthorizationHandler<HasNameRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasNameRequirement requirement)
{
var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
if (mvcContext != null)
{
var name = mvcContext.HttpContext.User.Identity.Name;
if(name != null && name != "")
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
}
return Task.CompletedTask;
}
}
_Layout.cshtml:
@if (await AuthorizationService.AuthorizeAsync(User, "HasName"))
{
...
}
_ViewImports.cshtml:
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService
问题出在 HasNameHandler 中。
var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
这一行是为了让我的授权块只在有 MVC 上下文时才起作用。因为视图没有访问 MVC 上下文的权限,所以基于视图的授权在没有点击 context.Succeed() 的情况下完成了授权。
我删除了它,而是使用传递到方法中的 AuthorizationContext。
var name = context.User.Identity.Name;
if(name != null && name != ""){
context.Succeed(requirement);
}
else {
context.Fail();
}
我的 ASP.NET Core 2.0 Web 应用程序出现奇怪的行为,授权在控制器级别通过,但在视图级别失败。
这是 ASP.NET Core 2.0 中的错误还是我的代码有问题?
//Controller中授权成功
信息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[1] 用户授权成功:(用户名)。
//进入控制器
信息:Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1] 使用参数 ((null) 执行操作方法 HomeController.Index (Bams) ) - 模型状态有效
...
//视图失败
信息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] 用户授权失败:(用户名)。
在 Startup.cs 中配置服务:
services.AddAuthorization(options => {
options.AddPolicy("HasName", policy => policy.Requirements.Add(new HasNameRequirement()));
});
HomeController.cs:
[Authorize(Policy="HasName")]
public class HomeController : Controller
{
public IActionResult Index(){
return View();
}
}
有名称要求:
public class HasNameRequirement : IAuthorizationRequirement {
public HasNameRequirement() { }
}
HasNameHandler:
public class HasNameHandler : AuthorizationHandler<HasNameRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasNameRequirement requirement)
{
var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
if (mvcContext != null)
{
var name = mvcContext.HttpContext.User.Identity.Name;
if(name != null && name != "")
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
}
return Task.CompletedTask;
}
}
_Layout.cshtml:
@if (await AuthorizationService.AuthorizeAsync(User, "HasName"))
{
...
}
_ViewImports.cshtml:
@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService
问题出在 HasNameHandler 中。
var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
这一行是为了让我的授权块只在有 MVC 上下文时才起作用。因为视图没有访问 MVC 上下文的权限,所以基于视图的授权在没有点击 context.Succeed() 的情况下完成了授权。
我删除了它,而是使用传递到方法中的 AuthorizationContext。
var name = context.User.Identity.Name;
if(name != null && name != ""){
context.Succeed(requirement);
}
else {
context.Fail();
}