Custom Bearer Token Authorization for ASP.Net Core

12,532

That would work, but it's kind of reinventing the wheel.

I good approach these days is to use JWTs, you can find more info about it here: http://www.jwt.io/

Some advantages are that it integrates quite nicely with asp.net core and you can also add some information to the token (username, role, etc). That way, you don't even need to access the database for validation (if you want to).

Also, storing keys in appsettings file could lead to accidentally adding them to your source-code manager (security). You could use user secrets for local development (or disable the key when environment = dev) and environment variables for production.

Here is one good example of how to use jwt with asp.net: https://jonhilton.net/2017/10/11/secure-your-asp.net-core-2.0-api-part-1-issuing-a-jwt/

Share:
12,532
Anton Swanevelder
Author by

Anton Swanevelder

Updated on June 05, 2022

Comments

  • Anton Swanevelder
    Anton Swanevelder almost 2 years

    Is this an acceptable implementation of a custom bearer token authorization mechanism?

    Authorization Attribute

    public class AuthorizeAttribute : TypeFilterAttribute
    {
        public AuthorizeAttribute(): base(typeof(AuthorizeActionFilter)){}
    }
    
    public class AuthorizeActionFilter : IAsyncActionFilter
    {
        private readonly IValidateBearerToken _authToken;
        public AuthorizeActionFilter(IValidateBearerToken authToken)
        {
            _authToken = authToken;
        }
    
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            const string AUTHKEY = "authorization";
            var headers = context.HttpContext.Request.Headers;
            if (headers.ContainsKey(AUTHKEY))
            {
                bool isAuthorized = _authToken.Validate(headers[AUTHKEY]);
                if (!isAuthorized)
                    context.Result = new UnauthorizedResult();
                else
                    await next();
            }
            else
                context.Result = new UnauthorizedResult();
        }
    }
    

    Validation Service. APISettings class is used in appSettings, but validation can be extended to use a database ... obviously :)

    public class APISettings
    {
        public string Key { get; set; }
    }
    
    public class ValidateBearerToken : IValidateBearerToken
    {
        private readonly APISettings _bearer;
    
        public ValidateBearerToken(IOptions<APISettings> bearer)
        {
            _bearer = bearer.Value;
        }
    
        public bool Validate(string bearer)
        {
            return (bearer.Equals($"Bearer {_bearer.Key}"));
        }
    }
    

    Implementation

    [Produces("application/json")]
    [Route("api/my")]
    [Authorize]
    public class MyController : Controller
    

    appSettings

    "APISettings": {
    "Key": "372F78BC6B66F3CEAF705FE57A91F369A5BE956692A4DA7DE16CAD71113CF046"
    

    }

    Request Header

    Authorization: Bearer 372F78BC6B66F3CEAF705FE57A91F369A5BE956692A4DA7DE16CAD71113CF046