提问人:user3715648 提问时间:2/13/2020 更新时间:2/26/2020 访问量:229
是否可以内联运行策略的所有处理程序,而不是使用属性?
Possible to run all handlers for a policy in-line instead of with an attribute?
问:
在我的大多数 API 上,我只是像这样进行授权:
[Authorize(Policy = "Foo")]
public MyApi()
我从NuGet获取此策略,但无法修改它。
对于我的某些 API,我并不总是希望有这个策略。这需要在运行时根据一些配置来弄清楚。我想要某种方式来内联运行它,并确保所有设置的处理程序都运行。
经过大量搜索,我发现我创建了一个 ,并用它来调用 .这似乎是我想要的,但我现在遇到的问题是所有处理程序都依赖 an 作为上下文中的资源。当通过属性完成授权时,这似乎会自动发生,而不是通过对 AuthorizeAsync 的调用。在这种情况下,它需要手动传入。我的代码现在看起来像这样:IAuthorizationService
AuthorizeAsync
AuthorizationFilterContext
public MyApi()
{
var allowed = await _authorizationService.AuthorizeAsync(User, null, "Foo").ConfigureAwait(false);
}
这似乎正确地遍历了我的所有处理程序,但由于缺少 .AuthorizationFilterContext
1) 这是正确的方法,还是有其他方法可以内联完成?我猜可能有某种方法可以创建我自己的策略来包装这个策略,我可以检查那里的配置,但如果有一个简单的内联方法,我更喜欢它。
2)如果这种方式有效,有没有一种好的方法可以得到?我尝试过手动创建它,但恐怕如果不从上下文中传入更多数据,这实际上并不正确,但我找不到任何好的例子/文档:AuthorizationFilterContext
new AuthorizationFilterContext(new ActionContext(HttpContext, HttpContext.GetRouteData(), new ActionDescriptor()), new IFilterMetadata[] { });
答:
当您在授权管道之外时,不会有。因此,不应使用 内联处理身份验证。AuthorizationFilterContext
IAuthorizationService
这似乎正确地遍历了我的所有处理程序,但由于缺少 .
AuthorizationFilterContext
听起来您可以控制身份验证处理程序。如果不需要,您是否尝试过在处理程序内部进行短路身份验证?
处理程序可以通过 DI 获取服务,因此您可以通过 IOptions 或 IHttpContextAccessor 等方式放置所需的运行时配置。
您不能创建自己的属性来继承当前属性并在内部解析策略吗?或者更好的是尝试使用Authorize
IAuthorizationPolicyProvider
class MyPolicyProvider : IAuthorizationPolicyProvider
{
private DefaultAuthorizationPolicyProvider BackupPolicyProvider { get; }
public MyPolicyProvider()
{
BackupPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
}
public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{
if (policyName.Equals("Foo"))
{
bool myConditionToAvoidPolicy = true;
if (myConditionToAvoidPolicy)
{
return Task.FromResult<AuthorizationPolicy>(null);
}
}
return BackupPolicyProvider.GetPolicyAsync(policyName);
}
}
这没有经过测试,但你可以在这里找到更多关于它的信息。
您的检查条件看起来像在以后发生,我认为这不是一个好主意。您的 api 方法易受攻击,并且在稍后完成检查时仍处于打开状态。但是,通过使用属性,您可以在更早的级别捕获它,并且仍然可以应用自定义逻辑。归根结底,它决定的要么是“是的,可以访问”,要么“不,你没有访问权限!以下未经测试,但应该可以让您继续前进:
public class CustomAuthorize : AuthorizeAttribute
{
private readonly PermissionAction[] permissionActions;
public CustomAuthorize(PermissionItem item, params PermissionAction[] permissionActions)
{
this.permissionActions = permissionActions;
}
public override void OnAuthorization(HttpActionContext actionContext)
{
var currentIdentity = System.Threading.Thread.CurrentPrincipal.Identity;
if (!currentIdentity.IsAuthenticated) {
// no access
}
bool myCondition = "money" == "happiness";
if(myCondition){
// do your magic here...
}
else{
// another magic...
}
}
}
评论