Reputation: 511
I have implemented an AuthorizationFilter for my API using IAsyncAuthorizationFilter, and would like to be able to pass information about the authorized user to the actions that have this Authorization filter. Since the filter is already retrieving that information, I would prefer to not have to retrieve it again within the action itself.
Looking through the AuthorizationFilterContext object, I see that we have access to the RouteValues of the request through the HTTPContext. Adding a new KeyValuePair to the RouteValues collection appears to do what I want, but feels like something that could be potentially problematic or that there could be a better way of accomplishing this.
Is there a "best practice" way of accomplishing this, or is my solution acceptable?
Example code:
public class AuthorizeAttribute : Attribute, IAsyncAuthorizationFilter
{
private string[] _PermittedRights;
public AuthorizeAttribute() : this(null) { }
public AuthorizeAttribute(string[] permittedRights)
{
_PermittedRights = permittedRights;
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
var authResult = await AuthenticationHelper.AuthenticateApiCallAsync(context.HttpContext.Request.Headers);
if (authResult.Succeeded == true)
{
context.HttpContext.Request.RouteValues.Add("AuthUser", authResult.AuthenticatedUser);
}
else
{
context.Result = new UnauthorizedResult();
}
}
}
Upvotes: 0
Views: 1810
Reputation: 18239
I think your method is feasible. Properties like TempData cannot be used here, and routing itself carries the relevant parameters of the action and the values of various endpoints. The RouteValues belong to the Request object, and its content will be saved to the end of this endpoint. Or you can pass the retrieved data through the RouteData of the context object.
And here is a demo:
AuthorizeAttribute :
public class AuthorizeAttribute : Attribute, IAsyncAuthorizationFilter
{
//...
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
context.RouteData.Values.Add("AuthUser", new { name="buble"});//Put the retrieved value into this object
/*var authResult = await AuthenticationHelper.AuthenticateApiCallAsync(context.HttpContext.Request.Headers);
...
*/
}
}
Receive in this way.
[Authorize]
public IActionResult index2()
{
var res= RouteData.Values["AuthUser"];
return Json("true");
}
result:
Upvotes: 1