Search code examples
c#asp.netasp.net-web-apiasp.net-web-api-filters

Authentication Filter not working with Authorization Filter in Web API


I am trying to create a custom Authentication filter for ASP.NET Web API. Below is the code for my authentication filter

public class IDPAuthenticationFilter : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        var identity = new ClaimsIdentity();
        identity.AddClaim(new Claim(ClaimTypes.Name, "testUser"));
        identity.AddClaim(new Claim(ClaimTypes.Role, "client"));
        identity.AddClaim(new Claim("testUser"));
        identity.AddClaim(new Claim("APP:USERID", "50123"));

        var principal = new GenericPrincipal(identity, new string[] { });
        Thread.CurrentPrincipal = principal;
        HttpContext.Current.User = principal;

        base.OnAuthorization(actionContext);
    }
}

I have configured the Authentication Filter globally and confirmed using break-point that the filter is getting called.

config.Filters.Add(new IDPAuthenticationFilter());

The issue is if I add [System.Web.Http.Authorize] attribute to any controller then I get 401 Unauthorized error. I am able to access user name using User.Identity.Name in the controller action, but if I add authorize attribute I get the error. Is there any thing I am missing.

Thanks for you time. Kindly add a comment in case any other information is required.


Solution

  • There were couple of things that I was doing wrong. First I needed to implement IAuthenticationFilter instead of AuthorizationFilterAttribute

    Second the way I was setting the identity was incorrect. Below is the code that worked for me.

    public class IDPAuthenticationFilter : Attribute, IAuthenticationFilter 
    {
    
        public bool AllowMultiple => false;
    
        public async Task AuthenticateAsync (HttpAuthenticationContext context, CancellationToken cancellationToken) 
        {
    
            HttpRequestMessage request = context.Request;
            AuthenticationHeaderValue authorization = request.Headers.Authorization;
    
            if (authorization == null) {
                return;
            }
            if (authorization.Scheme != "Bearer") {
                return;
            }
    
            var claims = new List<Claim> ();
            claims.Add (new Claim (ClaimTypes.Name, "testUser"));
            claims.Add (new Claim (ClaimTypes.Role, "client"));
            claims.Add (new Claim ("sub", "testUser"));
            claims.Add (new Claim("APP:USERID", "50123"));
    
            var identity = new ClaimsIdentity (claims, "Auth_Key");
    
            var principal = new ClaimsPrincipal (new [] { identity });
            context.Principal = principal;
            HttpContext.Current.User = context.Principal;
            Thread.CurrentPrincipal = context.Principal;
    
        }
    
    }