How do you create a custom AuthorizeAttribute in ASP.NET Core?

前端 未结 11 1239
春和景丽
春和景丽 2020-11-21 17:19

I\'m trying to make a custom authorization attribute in ASP.NET Core. In previous versions it was possible to override bool AuthorizeCore(HttpContextBase httpContext)

11条回答
  •  闹比i
    闹比i (楼主)
    2020-11-21 18:09

    As of this writing I believe this can be accomplished with the IClaimsTransformation interface in asp.net core 2 and above. I just implemented a proof of concept which is sharable enough to post here.

    public class PrivilegesToClaimsTransformer : IClaimsTransformation
    {
        private readonly IPrivilegeProvider privilegeProvider;
        public const string DidItClaim = "http://foo.bar/privileges/resolved";
    
        public PrivilegesToClaimsTransformer(IPrivilegeProvider privilegeProvider)
        {
            this.privilegeProvider = privilegeProvider;
        }
    
        public async Task TransformAsync(ClaimsPrincipal principal)
        {
            if (principal.Identity is ClaimsIdentity claimer)
            {
                if (claimer.HasClaim(DidItClaim, bool.TrueString))
                {
                    return principal;
                }
    
                var privileges = await this.privilegeProvider.GetPrivileges( ... );
                claimer.AddClaim(new Claim(DidItClaim, bool.TrueString));
    
                foreach (var privilegeAsRole in privileges)
                {
                    claimer.AddClaim(new Claim(ClaimTypes.Role /*"http://schemas.microsoft.com/ws/2008/06/identity/claims/role" */, privilegeAsRole));
                }
            }
    
            return principal;
        }
    }
    

    To use this in your Controller just add an appropriate [Authorize(Roles="whatever")] to your methods.

    [HttpGet]
    [Route("poc")]
    [Authorize(Roles = "plugh,blast")]
    public JsonResult PocAuthorization()
    {
        var result = Json(new
        {
            when = DateTime.UtcNow,
        });
    
        result.StatusCode = (int)HttpStatusCode.OK;
    
        return result;
    }
    

    In our case every request includes an Authorization header that is a JWT. This is the prototype and I believe we will do something super close to this in our production system next week.

    Future voters, consider the date of writing when you vote. As of today, this works on my machine.™ You will probably want more error handling and logging on your implementation.

提交回复
热议问题