问题描述
我已经使用IAsyncAuthorizationFilter为我的API实现了AuthorizationFilter,并且希望能够将有关授权用户的信息传递给具有此Authorization过滤器的操作。由于过滤器已经在检索该信息,所以我希望不必在操作本身中再次检索它。
通过AuthorizationFilterContext对象,我看到我们可以通过HTTPContext访问请求的RouteValues。将新的KeyValuePair添加到RouteValues集合出现即可完成我想要的操作,但感觉可能存在问题或有更好的方法来实现此目的。
是否有“最佳实践”的方式来完成此任务,或者我的解决方案可以接受吗?
示例代码:
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();
}
}
}
解决方法
我认为您的方法可行。像TempData这样的属性不能在这里使用,并且路由本身包含动作的相关参数以及各个端点的值。 RouteValues属于Request对象,其内容将保存到此端点的末尾。或者,您也可以通过上下文对象的RouteData传递检索到的数据。
这是一个演示:
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);
...
*/
}
}
以这种方式接收。
[Authorize]
public IActionResult index2()
{
var res= RouteData.Values["AuthUser"];
return Json("true");
}
结果: