【问题标题】:ASP.NET 5 Policy-Based Authorization Handle Not Being Called未调用 ASP.NET 5 基于策略的授权句柄
【发布时间】:2019-05-02 15:05:43
【问题描述】:

按照此处的文档,我尝试实施基于策略的身份验证方案。 http://docs.asp.net/en/latest/security/authorization/policies.html#security-authorization-handler-example

我遇到了在我的自定义 AuthorizationHandler 上没有调用我的 Handle 方法的问题。 (这里不扔)。它还确实注入了当前在构造函数中的依赖项。

这里是 AuthorizationHandler 代码。

using WebAPIApplication.Services;
using Microsoft.AspNet.Authorization;

namespace WebAPIApplication.Auth
{
    public class TokenAuthHandler : AuthorizationHandler<TokenRequirement>, IAuthorizationRequirement
    {
        private IAuthService _authService;

        public TokenAuthHandler(IAuthService authService)
        {
            _authService = authService;
        }

        protected override void Handle(AuthorizationContext context, TokenRequirement requirement)
        {
            throw new Exception("Handle Reached");
        }
    } 

    public class TokenRequirement : IAuthorizationRequirement
    {
        public TokenRequirement()
        {
        }
    }
}

在启动时我有

// Authorization
            services.AddSingleton<IAuthorizationHandler, TokenAuthHandler>()
                .AddAuthorization(options =>
                {
                    options.AddPolicy("ValidToken",
                        policy => policy.Requirements.Add(new TokenRequirement()));
                });

控制器方法是

// GET: api/values
        [HttpGet, Authorize(Policy="ValidToken")]
        public string Get()
        {
            return "test";
        }

点击此端点不会返回任何内容,并且在

的控制台中有警告
warn: Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker[0]
      Authorization failed for the request at filter 'Microsoft.AspNet.Mvc.Filters.AuthorizeFilter'.

我能够成功命中没有该属性的其他端点。

求救, 杰克

【问题讨论】:

  • 同样的问题。你有想过这个吗?
  • 是的,我在下面回答,它符合您对 adem 评论的评论

标签: c# asp.net authorization asp.net-core


【解决方案1】:

我把这个放在这里作为参考,因为我花了太长时间才弄清楚这个......

我已经实现了一个自定义需求和处理程序(为了测试而为空):

using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;

public class TestHandler : AuthorizationHandler<TestRequirement>, IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TestRequirement requirement)
    {
        context.Succeed(requirement);
        return Task.CompletedTask;
    }
}

public class TestRequirement : IAuthorizationRequirement
{

}

在我的Startup.csConfigureServices()部分注册:

services.AddAuthorization(options =>
{
    options.AddPolicy("Test", policy => policy.Requirements.Add(new TestRequirement()));
    // Other policies here
}

将其添加到我的控制器方法中:

[HttpGet]
[Authorize(Policy = "Test")]
public IActionResult Index()
{
    Return View();
}

但是对控制器方法的每个请求都会收到 403 错误(不是 401)!

原来,我没有在Startup.csConfigureServices()(依赖注入)部分注册TestHandler

services.AddSingleton<IAuthorizationHandler, TestHandler>();

希望这可以避免有人用头撞桌子。 :|

【讨论】:

  • 为我修复了它。尽管我非常喜欢在 AspNetCore 中包含 DI,但它有时会混淆您必须注册什么以及如何注册。
  • 感谢指出,我也犯了同样的错误。希望,.NetCore 将来会返回一些 rutime 错误而不是 403。
  • 我在这个问题上花了两天时间,结果发现这是我需要的答案......我觉得自己像个白痴。
  • 谢谢,我准备切换到另一个实现,但在最后一分钟找到了这篇文章
【解决方案2】:

在对 adem caglin 的评论中提到了这个问题的答案,所以支持他。

问题是AuthorizeFilter 在调用AuthorizationHandler 之前拒绝了请求。这是因为每次使用 Authorize 标签时,MVC 都会在管道中的 AuthorizationHandler 之前添加 AuthorizeFilter。这个AuthorizeFilter 检查是否有任何当前用户身份被授权。在我的情况下,没有与任何用户关联的授权身份,所以这总是会失败。

一个解决方案(IMO 有点老套)是插入一个中间件,该中间件将在任何 MVC 代码之前执行。该中间件将向用户添加一个通用的经过身份验证的身份(如果用户还没有)。

因此,AuthorizeFilter 检查将通过,AuthenticationHandler 方法上的Handle 方法将被执行,我们的问题将得到解决。中间件代码(需要在app.UseMvc();调用之前添加到Configure)如下

    app.Use(async (context, next) =>
    {
        if (!context.User.Identities.Any(i => i.IsAuthenticated))
        {
            context.User = new ClaimsPrincipal(new GenericIdentity("Unknown"));
        }
        await next.Invoke();
    });

此处概述了覆盖 AuthorizeFilter 的另一种方法 (Override global authorize filter in ASP.NET Core MVC 1.0)

引用此处的回复 (Asp.Net Core policy based authorization ends with 401 Unauthorized)

【讨论】:

    【解决方案3】:

    看看Asp.net Core Authorize Redirection Not Happening 我认为添加options.AutomaticChallenge = true; 可以解决您的问题。

    【讨论】:

    • 我认为这可能特定于 cookieAuthentication。当我打电话给services.AddAuthorization() 时,我得到一个没有AutomaticChallenge 字段的AuthorizationOptions 实例
    • 您使用哪种身份验证中间件?
    • 如果你使用[Authorize]属性没有认证,见stackoverflow.com/questions/37276005/…
    • 我想可能是这样。我在我的大多数路由上使用 JWT 身份验证,但我使用自定义 [Authorize] 属性的路由不需要令牌。所以默认的AuthorizeFilter 必须拒绝请求。我明天去看看
    猜你喜欢
    • 2022-01-17
    • 1970-01-01
    • 2018-12-28
    • 2021-11-07
    • 1970-01-01
    • 2016-09-13
    • 2016-06-07
    • 1970-01-01
    • 2019-12-31
    相关资源
    最近更新 更多