Hi @Maryan ,
if I implement ApiKey authorization in the web API, wouldn't be a problem or have a conflict with the JWT authorization?
If you directly implement APIKey authorization in the API (with JWT authorization), 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.
I assume you want to achieve that not matter use any of the authorization method (JWT or API Key), 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.
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards,
Dillion