首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >尝试在我的所有控制器中应用授权筛选器,但未使用IAuthorizationHandler

尝试在我的所有控制器中应用授权筛选器,但未使用IAuthorizationHandler
EN

Stack Overflow用户
提问于 2019-12-28 00:44:32
回答 3查看 346关注 0票数 0

我尝试定义一个授权策略,以应用于我所有控制器的所有方法。我正在尝试按照guidelines given here, in "Authorization for specific endpoints" subsection替换我之前的AuthorizeFilter,但它不起作用。

在我的Startup中,我有:

代码语言:javascript
运行
复制
app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapDefaultControllerRoute().RequireAuthorization();
});

ConfigureServices

代码语言:javascript
运行
复制
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
    .AddAzureADBearer(options => this.Configuration.Bind("AzureAd", options));

services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder()
        .AddRequirements(new MyRequirement(MyParams))
        .Build();
});
(...)
    services.AddTransient<IAuthorizationHandler, MyAuthorizationHandler>();

我有一个要求:

代码语言:javascript
运行
复制
public class MyRequirement : IAuthorizationRequirement
{
    public EntityType MyParams { get; private set; }

    public MyRequirement(MyParams myParams) { MyParams = myParams; }
}

和一个处理程序:

代码语言:javascript
运行
复制
public class MyAuthorizationHandler : AuthorizationHandler<MyRequirement>
{
    private readonly ILogger<MyAuthorizationHandler> logger;
    private readonly IHttpContextAccessor httpContextAccessor;

    public MyAuthorizationHandler(IHttpContextAccessor httpContextAccessor, ILogger<MyAuthorizationHandler> logger)
    {
        this.httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
        this.logger = logger;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement)
    {
---> Some things. I don't get here when I debug.       
    }
}

在我的控制器中,我没有放置任何装饰器,因为我希望将此授权策略应用于我的所有方法,这就是我重写DefaultPolicy的原因。

如果我进行调试,我不会像预期的那样在处理程序处停止。实际上,如果我在控制器中放置一个装饰器[Authorize],我就到此为止了,但正如我前面提到的,我试图避免在所有控制器中都编写这个装饰器。

为什么不工作?谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-01-09 21:17:27

我终于解决了这个问题。在startupConfigureServices

代码语言:javascript
运行
复制
services.AddAuthorization(options =>
{
    options.AddPolicy(
        "UserIsRegistered",
        new AuthorizationPolicyBuilder()
            .AddRequirements(new RegistrationRequirement())
            .Build());
});

然后我定义了RegistrationRequirement

代码语言:javascript
运行
复制
 public class RegistrationRequirement : IAuthorizationRequirement
 {
 }

然后我定义了RegistrationAuthorizationHandler

代码语言:javascript
运行
复制
public class RegistrationAuthorizationHandler : AuthorizationHandler<RegistrationRequirement>
    {
        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RegistrationRequirement requirement)
        {
---> LOGIC I WANT TO CHECK
            if (WHATEVER)
            {
                context.Succeed(requirement);
            }
            return Task.CompletedTask;
        }
    } 

最后还是在startup中的Configure中:

代码语言:javascript
运行
复制
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers().RequireAuthorization("UserIsRegistered");
});

总而言之,我的主要问题是使用MapDefaultControllerRoute而不是MapControllers……

票数 1
EN

Stack Overflow用户

发布于 2019-12-28 01:30:33

我的理解是,即使使用默认策略,也需要[Authorize]属性。当我需要以这种方式保护我的所有端点时,我通常会做的是创建一个具有此属性的抽象基本控制器,然后让我的其他控制器继承它。

例如:

基本控制器

代码语言:javascript
运行
复制
[Authorize]
public abstract class MyBaseController : Controller //use Controller for mvc controller or ControllerBase for api controller
{
//base controller methods and properties
}

其他控制器:

代码语言:javascript
运行
复制
public class MyOtherController : MyBaseController 
{
//controller methods and properties
}
票数 1
EN

Stack Overflow用户

发布于 2019-12-28 13:41:40

试试这个:

代码语言:javascript
运行
复制
public void ConfigureServices(IServiceCollection services)
{         
    services.AddHttpContextAccessor();
    services.AddTransient<IAuthorizationHandler, MyAuthorizationHandler>();

    services.AddControllersWithViews(config =>
    {
        var policy = new AuthorizationPolicyBuilder()
                .AddRequirements(new MyRequirement(MyParams))
            .Build();
        config.Filters.Add(new AuthorizeFilter(policy));
    });

    services.AddDbContext<MvcProj3Context>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("MvcProj3Context")));
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseAuthentication();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");

    });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59503646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档