在.NET Core中使用JWT令牌或API密钥的授权机制 [英] Authorization mechanism which uses JWT token OR API-key in .NET Core

查看:223
本文介绍了在.NET Core中使用JWT令牌或API密钥的授权机制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是.NET Core 3.1的新手,我正在尝试创建一种授权机制,该机制将使用JWT令牌或API密钥.该机制将用于除服务于登录机制的端点之外的所有端点.我试图以显示

请参考本文.

此外,您还可以考虑基于Authorization方法对动作方法进行分组,对于与API密钥相关的动作方法或控制器,仅添加自定义API-Key属性,因为该动作方法需要进行JWT身份验证,只需添加 [Authorize] 属性.

I'm new to .NET Core 3.1 and I'm trying to create an authorization mechanism, that will use JWT tokens or API-key. This mechanism will be used for all endpoints except endpoints that will serve the login mechanism. I was trying to create an API-key attribute in a way shown here and decorate all controllers with it but, this was only working when no [Authorize] attribute was set. When I set [Authorize] attribute and set a breakpoint in my API-key attribute it will never be reached and I'm getting 401 Unauthorized as a response. Is there any chance to have both authorization methods working in parallel? If so, please guide me on how to achieve that.

Sample code can be found here

解决方案

I was trying to create an API-key attribute in a way shown here and decorate all controllers with it but, this was only working when no [Authorize] attribute was set. When I set [Authorize] attribute and set a breakpoint in my API-key attribute it will never be reached and I'm getting 401 Unauthorized as a response.

The issue relates that when using custom API-Key attribute with the [Authorize] attribute together, the controller or the action method will be configured both JWT authentication and API-Key validation, in the request header, it should contain both the JWT token and API-Key. If any of them are missing, it will display a 401 Unauthorized error.

Is there any chance to have both authorization methods working in parallel? If so, please guide me on how to achieve that.

Do you mean use any of the authorization method, you could access the related action method, if that is the case, you could try to use the custom the Authorization attributes.

For example: create a CustomAuthorization with the following code:

[AttributeUsage(AttributeTargets.Class)]
public class CustomAuthorization : Attribute, IAuthorizationFilter
{ 
    /// <summary>  
    /// This will Authorize User  
    /// </summary>  
    /// <returns></returns>  
    public void OnAuthorization(AuthorizationFilterContext filterContext)
    {

        if (filterContext != null)
        {
            //get the authorization header
            Microsoft.Extensions.Primitives.StringValues authTokens;
            filterContext.HttpContext.Request.Headers.TryGetValue("Authorization", out authTokens);

            var _token = authTokens.FirstOrDefault();

            if (_token != null)
            {
                string authToken = _token;
                if (authToken != null)
                {
                    if (IsValidToken(authToken))
                    {
                        filterContext.HttpContext.Response.Headers.Add("Authorization", authToken);
                        filterContext.HttpContext.Response.Headers.Add("AuthStatus", "Authorized");

                        filterContext.HttpContext.Response.Headers.Add("storeAccessiblity", "Authorized");

                        return;
                    }
                    else
                    {
                        filterContext.HttpContext.Response.Headers.Add("Authorization", authToken);
                        filterContext.HttpContext.Response.Headers.Add("AuthStatus", "NotAuthorized");

                        filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        filterContext.HttpContext.Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "Not Authorized";
                        filterContext.Result = new JsonResult("NotAuthorized")
                        {
                            Value = new
                            {
                                Status = "Error",
                                Message = "Invalid Token"
                            },
                        };
                    }

                }

            }
            else
            {
                //if the request header doesn't contain the authorization header, try to get the API-Key.
                Microsoft.Extensions.Primitives.StringValues apikey;
                var key = filterContext.HttpContext.Request.Headers.TryGetValue("ApiKey", out apikey);
                var keyvalue = apikey.FirstOrDefault();

                //if the API-Key value is not null. validate the API-Key.
                if(keyvalue != null)
                {
                    filterContext.HttpContext.Response.Headers.Add("ApiKey", keyvalue);
                    filterContext.HttpContext.Response.Headers.Add("AuthStatus", "Authorized");

                    filterContext.HttpContext.Response.Headers.Add("storeAccessiblity", "Authorized");

                    return;
                }

                
                filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                filterContext.HttpContext.Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = "Please Provide authToken";
                filterContext.Result = new JsonResult("Please Provide auth Token")
                {
                    Value = new
                    {
                        Status = "Error",
                        Message = "Please Provide auth Token"
                    },
                };  
            }
        }
    }

    public bool IsValidToken(string authToken)
    {
        //validate Token here  
        return true;
    }
}

Then, use the above CustomAuthorization in the API controller:

[Route("api/[controller]")]
[ApiController]
//[Authorize]
//[ApiKey]
[CustomAuthorization]
public class ValuesController : ControllerBase
{
    // GET: api/<ValuesController>
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

The result like this:

Refer this article.

Besides, you could also consider group the action method based on the Authorization method, for the API-key related action method or controller, only add the custom API-Key attribute, for the action method needs to JWT authentication, just add the [Authorize] attribute.

这篇关于在.NET Core中使用JWT令牌或API密钥的授权机制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆