【问题标题】:Check whether the allow anonymous is on or not in ASP.NET Core检查 ASP.NET Core 中是否允许匿名
【发布时间】:2020-03-04 10:06:47
【问题描述】:

我需要一种方法来检查“允许匿名”是否在控制器操作中打开/关闭。是否来自控制器属性,动作属性

[允许匿名]

或者在 MvcOptions 中设置为过滤器

opts.Filters.Add(new AllowAnonymousFilter());

有可能吗?

【问题讨论】:

  • 这感觉就像你在尝试做其他事情,也许是XY Problem。你这样做是为了解决什么问题?
  • 我有一个 API 端点,它必须保护图像。所以你有一次使用令牌,你需要作为查询传递,因为浏览器。对于自定义身份验证器的这一端点实现,我认为太多了。另一方面,对于端到端测试和开发目的,我需要判断它是否应该进行身份验证。

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


【解决方案1】:

您似乎需要在请求期间检查控制器和操作是否包含来自您的自定义身份验证过滤器的AllowAnonymousAttribute。所以你可以这样做:

public class CustomAuthorizationFilter : IAsyncAuthorizationFilter
{
    public async Task OnAuthorizationAsync(AuthorizationFilterContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException(nameof(filterContext));
        }

        bool hasAllowAnonymous = filterContext.ActionDescriptor.EndpointMetadata
                                 .Any(em => em.GetType() == typeof(AllowAnonymousAttribute)); //< -- Here it is

        if (hasAllowAnonymous) return;

        // Do your authorization check here
    }
}

【讨论】:

  • 如果在 MvcOptions 中设置了 AllowAnonymousFilter,这将不起作用,至少对于 dotnet core 3.1。扫描 filterContext.ActionDescriptor.FilterDescriptors 就可以了。
【解决方案2】:

鉴于您评论中的额外信息。这似乎与您重置密码的方式相同。

对于密码重置,您在请求中包含一次性密码重置令牌(以及密码/验证密码等)并取消令牌。

在您的情况下,我会做同样的事情 - 使用 [AllowAnonymous] 显式装饰操作并验证一次性令牌。您的操作不应该关心 AllowAnonymous 过滤器是否已通过属性或选项应用于操作。

更新 想多了,有一种简单的方法可以根据构建配置禁用它。将属性包装在 #if preprocessor directive 中,并创建定义条件编译符号的构建配置。详情见this answer

#if DISABLE_ALLOW_ANONYOMOUS
    [AllowAnonymous]
#endif
    public IActionResult GetPicture(string token){
        ...

然后您可以构建一个测试特定版本,其中 AllowAnonymous 被禁用。

你也可以用 MvcOptions 做同样的事情:

#if DISABLE_ALLOW_ANONYOMOUS
    opts.Filters.Add(new AllowAnonymousFilter());
#endif

【讨论】:

  • 这实际上是我目前的状态。但我希望能够通过 AllowAnonymousFilter 关闭。例如,我的控制器操作将像这样开始。 if (!IsAnonymousAllowed) await _authenticationService.AuthorizeFileAsync(accessToken, requestedObject, requestedFilename);
  • 为什么要能够关闭它?
  • 听起来有点可疑,如果您将其关闭,那么您并没有通过生产环境中存在的代码测试代码/路径。在我看来,这样做会使测试无效。
  • 另外,我原以为启用它实际上会更容易 - 无需检查用户凭据,也不需要这样做所需的所有数据。
  • 使用所有这些额外信息编辑原始问题也是一个好主意。
【解决方案3】:
public class MyController : Controller
{
    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        var anonActionAttributes = filterContext.ActionDescriptor
            .GetCustomAttributes(typeof(System.Web.Mvc.AllowAnonymousAttribute), true);

        var anonControllerAttributes = filterContext.ActionDescriptor.ControllerDescriptor
            .GetCustomAttributes(typeof(System.Web.Mvc.AllowAnonymousAttribute), true);

        if (anonActionAttributes.Length > 0 || anonControllerAttributes.Length > 0)            
            IsAllowAnonymous = true;

        base.OnAuthorization(filterContext);
    }

    bool IsAllowAnonymous { get; set; } = false;    
}

如果您觉得这个答案有帮助,请点赞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多