Nig*_*888 5 c# asp.net-mvc dependency-injection asp.net-core asp.net-core-2.0
我正在尝试编写基于策略的授权处理程序.处理程序的业务逻辑需要使用id通过默认路由传递的当前请求的记录.
[Authorize(Roles = "TaskAdmin", Policy = "RecordOwner")]
public IActionResult Index(int id) // <-- Need this id
{
// <snip>
return View();
}
Run Code Online (Sandbox Code Playgroud)
这是我需要访问id路由值的类.
public class RecordOwnerHandler : AuthorizationHandler<RecordOwnerRequirement>
{
private readonly ApplicationDbContext dbContext;
public RecordOwnerHandler(ApplicationDbContext dbContext)
{
this.dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RecordOwnerRequirement requirement)
{
if (IsUserAuthorized(context))
{
context.Succeed(requirement);
}
//TODO: Use the following if targeting a version of
//.NET Framework older than 4.6:
// return Task.FromResult(0);
return Task.CompletedTask;
}
private bool IsUserAuthorized(AuthorizationHandlerContext context)
{
//****************************************
// Need the id here...
//****************************************
// Return the result
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// *** Add policy for record owner ***
services.AddAuthorization(options =>
{
options.AddPolicy("RecordOwner", policy =>
policy.Requirements.Add(new RecordOwnerRequirement()));
});
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
// *** Register record owner handler with the DI container ***
services.AddTransient<IAuthorizationHandler, RecordOwnerHandler>();
services.AddMvc();
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用IHttpContextAccessoras作为构造函数参数RecordOwnerHandler,但IHttpContextAccessor.HttpContext似乎不包含RouteData请求.
我做了几次谷歌搜索,看看是否有任何关于如何做到这一点的信息,并且空白.
然后我挖掘了路由和模型绑定的源代码,但似乎找不到用于将路由值注入服务的抽象.
我意识到我可以尝试从URL中解析这些信息,但我希望有一种更清晰的方法来获取价值.
那么,如何在ASP.NET Core 2.0中访问服务内部的路由值和/或值提供者数据?
可以使用ActionContextAccessor该类访问路径值.
services.AddTransient<IActionContextAccessor, ActionContextAccessor>();
Run Code Online (Sandbox Code Playgroud)
public class RecordOwnerHandler : AuthorizationHandler<RecordOwnerRequirement>
{
private readonly ApplicationDbContext dbContext;
private readonly IActionContextAccessor actionContextAccessor;
public RecordOwnerHandler(ApplicationDbContext dbContext, IActionContextAccessor actionContextAccessor)
{
this.dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
this.actionContextAccessor = actionContextAccessor ?? throw new ArgumentNullException(nameof(actionContextAccessor));
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RecordOwnerRequirement requirement)
{
if (IsUserAuthorized(context))
{
context.Succeed(requirement);
}
//TODO: Use the following if targeting a version of
//.NET Framework older than 4.6:
// return Task.FromResult(0);
return Task.CompletedTask;
}
private bool IsUserAuthorized(AuthorizationHandlerContext context)
{
// Now the id route value can be accessed directly...
var id = this.actionContextAccessor.ActionContext.RouteData.Values["id"];
// Use the dbContext to compare the id against the database...
// Return the result
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
注意:我仍然想找到一种方法来访问值提供程序来执行此操作,因此如果通过路由值,查询字符串,表单值等传递参数也无关紧要.
小智 7
为了供将来参考,从 .NET Core 5.0 开始,现在改为传递 HttpContext,因此您可以执行以下操作:
if (context.Resource is HttpContext httpContext)
{
var value = httpContext.GetRouteValue("key");
}
Run Code Online (Sandbox Code Playgroud)
请参阅此参考[AspNetCore] 端点路由中的授权资源现在将是 HttpContext
| 归档时间: |
|
| 查看次数: |
2430 次 |
| 最近记录: |