gpt4 book ai didi

c# - ASP.NET Core 3.0 策略重定向

转载 作者:行者123 更新时间:2023-12-05 02:59:08 24 4
gpt4 key购买 nike

我们有这部分代码控制某些服务高级页面。对于没有高级成员(member)资格的人,拒绝方法会重定向到升级页面。

代码在 asp.NET core 2 上运行完美,但在 asp.NET core 3 上运行失败。context.Resource 不再是 AuthorizationFilterContext 类型,但 Endpoint 不提供 Result 成员。

¿如何使用 asp.Net core 3 上提供的新 Enpoint 使页面重定向?

public Task Deny(AuthorizationHandlerContext context, SubscriptionRequirement requirement)
{
var mvcContext = context.Resource as AuthorizationFilterContext;
if (mvcContext == null)
return Task.CompletedTask;

mvcContext.Result = new RedirectToActionResult("Upgrade", "Subscription", new { ReturnUrl = _contextAccessor.HttpContext.Request.Path });
context.Succeed(requirement);
return Task.CompletedTask;
}

最佳答案

根据 SOC 负责人的说法,将授权与响应重定向混在一起似乎不是一个好的做法。

相反,您可以将您的授权逻辑包装到一个策略中,然后调用 IAuthorizationService 并在您需要的任何地方/任何时间重定向。

假设您定义了“高级成员(member)资格”政策。然后您可以毫不费力地使用中间件/资源过滤器/ Action 过滤器甚至 Action 方法重定向请求。例如,我创建 MembershipResourceFilter 如下:

public class MembershipResourceFilter : IAsyncResourceFilter
{
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
{
var HttpContext = context.HttpContext;
var authZ = HttpContext.RequestServices.GetRequiredService<IAuthorizationService>();
var routeData= context.RouteData;
var result = await authZ.AuthorizeAsync(HttpContext.User, routeData,"premium membership");
if(!result.Succeeded)
{
context.Result = new RedirectToActionResult("Upgrade", "Subscription", new { ReturnUrl = HttpContext.Request.Path });
}
await next();
}
}

我使用以下策略测试了上面的代码,它对我来说工作正常。

services.AddAuthorization(o =>{
o.AddPolicy("premium membership", pb => pb
.RequireAuthenticatedUser()
.RequireAssertion((context)=>{
// check current context.User has premium membership
var user = context.User;
var routeData = context.Resource as RouteData;
if(routeData != null){
try{
var controller = routeData.Values["controller"]?.ToString();
var action = routeData.Values["action"]?.ToString();
// now you get the route value
if(controller == "Home" && action == "Action"){
// ...
return true;
}
}catch{
return false;
}
}
return false;
})
);
});

[编辑]

如果您不想更改[Authorize("Premium")],您可以创建一个简单的中间件而不是资源过滤器:

    ...
app.UseAuthentication();
app.UseRouting();


app.Use(async(ctx,next)=>{
var ep= ctx.Features.Get<IEndpointFeature>()?.Endpoint;
var authAttr = ep?.Metadata?.GetMetadata<AuthorizeAttribute>()
if(authAttr!=null && authAttr.Policy == "premium membership"){
var authService = ctx.RequestServices.GetRequiredService<IAuthorizationService>();
var result = await authService.AuthorizeAsync(ctx.User, ctx.GetRouteData(),authAttr.Policy);
if(!result.Succeeded)
{
var path = $"/Subscription/Upgrade?ReturnUrl={ctx.Request.Path}";
ctx.Response.Redirect(path) ;
return;
}
}
await next();
});

app.UseAuthorization();
app.UseEndpoints(endpoints =>{ ... });

中间件和资源过滤器基本上做同样的事情:调用授权服务并在需要时重定向。

关于c# - ASP.NET Core 3.0 策略重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58320155/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com