在asp.net核心中找不到用户的authorize属性

时间:2019-02-08 09:03:41

标签: asp.net-core-mvc authorization

我只想授权用户

[Authorize(Users = "anupam,ashwin")]  
public ActionResult AddArticle()  
{  
   return View();  
}  

Reference Here

但是我只在Roles中找到了AuthorizeAttribute,如下所示

enter image description here

我想使用Users属性进行Authorize,asp.net核心中还有其他替代方法吗?

1 个答案:

答案 0 :(得分:2)

您所引用的文章适用于ASP.NET MVC,而不适用于ASP.NET Core。通常,您应该忽略那里的所有内容,因为它不再适用。

似乎ASP.NET Core删除了对在Users中指定AuthorizeAttribute的支持(尽管坦率地说,我并不知道ASP.NET MVC首先拥有它)。不过,可以通过策略模仿此功能:

services.AddPolicy("MustBeJoeOrBob", p =>
    p.RequireAssertion(c =>
        new[] { "Joe", "Bob" }.Contains(c.User.Identity.Name)));

然后:

[Authorize(Policy = "MustBeJoeOrBob")]

但是,如果不清楚,则需要进行一定程度的硬编码,并且您需要针对每个不同的用户组使用单独的策略。例如,如果一个不同的操作只能由Joe和Mary访问,而不能 Bob访问,那么您还需要添加一个“ MustBeJoeOrMary”策略。那会很快变得乏味。

从技术上讲,有一种方法可以让一个策略处理任何给定的用户列表,但是实现并非易事。从本质上讲,您必须创建自定义AuthorizeAttribute,然后才能传递各种数据。但是,实际的授权仍然需要基于策略,因此您基本上只是将传入的值映射到具有标准前缀的自定义策略名称。例如:

public class UsersAuthorizeAttribute : AuthorizeAttribute
{
    private const string PolicyPrefix = "MustBeUsers"

    public UsersAuthorizeAttribute(string users)
    {
        Users = users;
    }

    public string Users
    {
        get => Policy.Substring(PolicyPrefix.Length);
        set => $"{PolicyPrefix}{value}";
    }
}

然后,您可以应用以下属性:

[UsersAuthorize("Joe,Bob")]

这实际上与以下操作相同:

[Authorize(Policy = "MustBeUsersJoe,Bob")]

换句话说,这只是创建“动态”策略名称的简便方法。但是,您现在需要一个策略处理程序,因此您要么回到同一轮为每种可能的用户组合创建一个策略处理程序,要么必须创建一个自定义策略提供程序。然后,该策略提供者可以仅查看前缀“ MustBeUsers”,并使用类似MustBeUsersAuthorizationHandler的名称来满足该策略,将其余的策略名称(即实际用户名)传递到处理程序中,以便进行评估。但是,ASP.NET Core将仅使用一个策略提供程序,因此,一旦订阅了自定义策略提供程序,还需要确保它也支持其他策略,或者至少在内部将策略处理委托给默认提供程序。 The docs go into greater detail,但可以说,您可以开始快速进入杂草。

老实说,这整个方法感觉像是一个巨大的漏洞,对于文档实际上详细描述了如何实现它,我感到非常惊讶。如果您真的需要类似的东西,这可能是有道理的,但是在您的情况下,我认为您缺少了一件至关重要的事情:您只能使用角色。

如果只希望Joe和Bob可以访问特定操作,则只需创建一个角色并将其分配给该角色即可。然后指定该角色:

[Authorize(Roles = "JoeAndBobsRole")]

这是角色的主要作用,您实际上是在尝试避开这些角色,并以不同的方式实现相同的功能。老实说,这也许就是为什么Users在ASP.NET Core中最初不存在的原因。