Sunday, October 18, 2020

[.NET core] AddPolicy to Authorize on MVC controller

Sometimes when you are using C# identity, the [Authorize] attribute is not enough,for example, you want additional check not only claims or role, then you can try add policy to make it. 

In this example, we assume a part of method need check token in user claims before access, here is how to implement it. 

1.add a AuthorizationHandler for your policy 
 Handler/AuthorizeTokenHandler.cs
namespace Example.Handler
{
    // Custom AuthorizationHandler for check token in claim
    public class AuthorizeTokenHandler : AuthorizationHandler<TokenRequirement>
    {
        private readonly AuthService _auth;

        public AuthorizeTokenHandler(AuthService auth)
        {
            _auth = auth;
        }
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TokenRequirement requirement)
        {
            //no token claim
            if (!context.User.HasClaim(x => x.Type == "Token"))
            {
                context.Fail();
                return Task.CompletedTask;
            }

            var username = context.User.FindFirst(ClaimTypes.Name).Value;
            var token = context.User.FindFirst("Token").Value;

            #region check token
            if (_auth.CheckToken(username,token))
            {
                context.Succeed(requirement);
            }
            else
            {
                context.Fail();
            }
            #endregion

            return Task.CompletedTask;
        }
    }

    public class TokenRequirement : IAuthorizationRequirement
    {
    }

2. add to startup, in ConfigureServices

            //handler
            services.AddSingleton<IAuthorizationHandler, AuthorizeTokenHandler>();
            
            //add policy
            services.AddAuthorization(options =>
            {
                options.AddPolicy("TokenRequire", policy =>
                    policy.Requirements.Add(new TokenRequirement()));
            });

3. apply policy to Authorize when you need

[Authorize(Policy = "TokenRequire")]
[HttpPost]
public ApiResult SomeMethod()
{
}

That's all, enjoy it.

No comments:

Post a Comment