首页 > C# > 如何在 ASP.NET 核心中创建自定义授权属性?

如何在 ASP.NET 核心中创建自定义授权属性?

上一篇 下一篇

我正在尝试在 ASP.NET Core 中创建自定义授权属性。在以前的版本中,可以覆盖 .但这在 中不再存在。bool AuthorizeCore(HttpContextBase httpContext)AuthorizeAttribute

当前创建自定义授权属性的方法是什么?

我正在尝试完成什么:我在标头授权中收到会话 ID。通过该 ID,我将知道特定操作是否有效。

分割线

网友回答:

ASP.Net 核心团队建议的方法是使用此处完整记录的新策略设计。新方法背后的基本思想是使用新属性来指定“策略”(例如 在应用程序中注册策略以执行某些代码块(即确保用户具有年龄为 18 岁或以上的年龄声明)。[Authorize][Authorize( Policy = "YouNeedToBe18ToDoThis")]Startup.cs

策略设计是对框架的重要补充,ASP.Net 安全核心团队的引入值得称赞。也就是说,它并不适合所有情况。此方法的缺点是,它无法为最常见的需求提供方便的解决方案,即简单地断言给定的控制器或操作需要给定的声明类型。如果应用程序可能有数百个离散权限来管理单个 REST 资源上的 CRUD 操作(“CanCreateOrder”、“CanReadOrder”、“CanUpdateOrder”、“CanDeleteOrder”等),新方法要么需要在策略名称和声明名称之间进行重复的一对一映射(例如,),要么编写一些代码在运行时执行这些注册(例如,从数据库中读取所有声明类型并在循环中执行上述调用)。在大多数情况下,这种方法的问题在于它是不必要的开销。options.AddPolicy("CanUpdateOrder", policy => policy.RequireClaim(MyClaimTypes.Permission, "CanUpdateOrder));

虽然 ASP.Net 核心安全团队建议永远不要创建自己的解决方案,但在某些情况下,这可能是最谨慎的选择。

下面是一个实现,它使用 提供一种简单的方法来表达给定控制器或操作的声明要求:IAuthorizationFilter

public class ClaimRequirementAttribute : TypeFilterAttribute
{
    public ClaimRequirementAttribute(string claimType, string claimValue) : base(typeof(ClaimRequirementFilter))
    {
        Arguments = new object[] {new Claim(claimType, claimValue) };
    }
}

public class ClaimRequirementFilter : IAuthorizationFilter
{
    readonly Claim _claim;

    public ClaimRequirementFilter(Claim claim)
    {
        _claim = claim;
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var hasClaim = context.HttpContext.User.Claims.Any(c => c.Type == _claim.Type && c.Value == _claim.Value);
        if (!hasClaim)
        {
            context.Result = new ForbidResult();
        }
    }
}


[Route("api/resource")]
public class MyController : Controller
{
    [ClaimRequirement(MyClaimTypes.Permission, "CanReadResource")]
    [HttpGet]
    public IActionResult GetResource()
    {
        return Ok();
    }
}

分割线

网友回答:

我是 asp.net 安全人员。首先,让我道歉,除了音乐商店示例或单元测试之外,这些都没有记录,并且它们仍在公开的 API 方面进行改进。详细文档在这里。

我们不希望您编写自定义授权属性。如果你需要这样做,我们做错了什么。相反,您应该编写授权要求

授权作用于标识。标识是通过身份验证创建的。

您在评论中说要检查标题中的会话 ID。您的会话 ID 将是身份的基础。如果要使用该属性,则需要编写身份验证中间件来获取该标头并将其转换为经过身份验证的 .然后,您将在授权要求中检查这一点。授权要求可以随心所欲地复杂,例如,这里有一个对当前身份进行出生日期声明,如果用户超过 18 岁,则会授权;AuthorizeClaimsPrincipal

public class Over18Requirement : AuthorizationHandler<Over18Requirement>, IAuthorizationRequirement
{
  public override void Handle(AuthorizationHandlerContext context, Over18Requirement requirement)
  {
    if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth))
    {
      context.Fail();
      return;
    }

    var dobVal = context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth).Value;
    var dateOfBirth = Convert.ToDateTime(dobVal);
    int age = DateTime.Today.Year - dateOfBirth.Year;
    if (dateOfBirth > DateTime.Today.AddYears(-age))
    {
      age--;
    }

    if (age >= 18)
    {
      context.Succeed(requirement);
    }
    else
    {
      context.Fail();
    }
  }
}

然后在你的函数中,你会把它连接起来ConfigureServices()

services.AddAuthorization(options =>
{
    options.AddPolicy("Over18", 
        policy => policy.Requirements.Add(new Authorization.Over18Requirement()));
});

最后,将其应用于控制器或操作方法

[Authorize(Policy = "Over18")]

分割线

网友回答:

看来有了 ASP.NET Core 2,就可以再次继承了,你只需要也实现(或):AuthorizeAttributeIAuthorizationFilterIAsyncAuthorizationFilter

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class CustomAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter
{
    private readonly string _someFilterParameter;

    public CustomAuthorizeAttribute(string someFilterParameter)
    {
        _someFilterParameter = someFilterParameter;
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var user = context.HttpContext.User;

        if (!user.Identity.IsAuthenticated)
        {
            // it isn't needed to set unauthorized result 
            // as the base class already requires the user to be authenticated
            // this also makes redirect to a login page work properly
            // context.Result = new UnauthorizedResult();
            return;
        }

        // you can also use registered services
        var someService = context.HttpContext.RequestServices.GetService<ISomeService>();

        var isAuthorized = someService.IsUserAuthorized(user.Identity.Name, _someFilterParameter);
        if (!isAuthorized)
        {
            context.Result = new StatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
            return;
        }
    }
}

模板简介:该模板名称为【如何在 ASP.NET 核心中创建自定义授权属性?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【C#】栏目查找您需要的精美模板。

相关搜索
  • 下载密码 lanrenmb
  • 下载次数 340次
  • 使用软件 Sublime/Dreamweaver/HBuilder
  • 文件格式 编程语言
  • 文件大小 暂无信息
  • 上传时间 04-08
  • 作者 网友投稿
  • 肖像权 人物画像及字体仅供参考
栏目分类 更多 >
热门推荐 更多 >
响应式 企业网站 微信模板 单页式简历模板 微信公众平台 微信文章 微信图片 微信素材 html5 自适应
您可能会喜欢的其他模板