ASP.net5中的授权

3

我正在尝试查看ASP.net5中是否有适用于我的应用程序授权的“开箱即用”的内容。我正在使用基于组/权限的授权方法。使用Identity3,我将角色用作组,然后从此创建了权限。每个权限都有一个链接到它的资源和1个或多个值,例如:

资源=页面,权限=添加、更新、查看、删除

另一个复杂之处在于组具有动态名称和动态权限!

我已经开始阅读ASP.net5中的授权相关内容,似乎找到了一些称为策略(Policies)的东西,听起来不错。它似乎强制你使用声明(Claims),如果我使用ClaimsTransformer从数据库中获取所有权限并将它们添加为声明,则可以实现。但是,我是否正确地认为我需要在每个资源上为每个权限创建一个策略?那看起来需要进行很多设置。

ASP.net5中是否有我不知道的任何内容可以使用?比如这样的属性:

[Authorize("Page", "Delete")]

我可以将其添加到PageController的Delete方法中。如果必须使用某种服务并将其注入控制器以实现此目的,那么这也是可以的。

在asp.net中,除了位置和文件夹结构之外,没有任何变化。是的,有一些新的东西,比如startup.cs文件,但mvc工作流程的核心功能没有任何改变。所以请再次仔细查看所有的代码和引用。如果一切正常,它将会工作。 - Piyush Barua
4个回答

0

我使用 AspNet.Security.OpenIdConnect.Server 进行授权。但您也可以查看 OpenIddict

在任何情况下,您都可以像这样向任何方法添加Authorize属性:

[Authorize(Roles = "Administrator,SimpleUser,AnOtherRole")]
public void MyMethod() {}

用户组和权限是动态的,所以这样做不起作用。 - Gillardo
你可以随时创建自定义的授权属性,并在其中执行任何操作。 - Manos Pasgiannis

0

基于资源的授权可能能够满足您的需求,但我对页面作为资源而不是页面所执行的操作有些困惑。

以您的Page/Delete组合为例,我想象中的情况是,与其将资源定义为页面,您的Page Delete操作会带有一个参数,指示要删除的页面?(如果不是这种情况,那么这种方法当然行不通)

在这种情况下,您可以这样做:

[Authorize]
public class PageController : Controller
{
    IAuthorizationService _authorizationService;

    public PageController(IAuthorizationService authorizationService)
    {
        _authorizationService = authorizationService;
    }

    public Delete(int pageId)
    {
        var page = pageRepo.GetPage(pageId);
        if (await authorizationService.AuthorizeAsync(User, page,  Operations.Delete))
        {
            return View(page);
        }
        else
        {
            return new ChallengeResult();
        }
    }
}

为了实现这一点,您需要编写一个基于页面和操作需求的处理程序(或任何旧需求,但参数化的操作需求意味着您可以编写一个单独的处理程序并相应地进行分支)。
我们非常努力地试图摆脱将数据放入属性中,并将其移入要求中,因为在属性中的数据实际上是维护的噩梦。
还有一件事需要注意;由于处理程序通过 DI 解析,因此您可以将用户权限解析器注入到处理程序中,这将避免使用声明转换。

也许“page”是个不好的名字,但那是我的对象名称。所以这在一个PageController中(可以称为Company、Contact或其他)。我不需要根据模型进行验证,但我需要检查用户是否有权限(我想我可以用权限来代替页面?)。能否使用此方法完成此操作,因为我更喜欢使用属性而不是特性。另外,Operations.Delete是什么? - Gillardo
首先,请按照答案开头的链接。那里详细介绍了操作是什么。 - blowdart
第二点 - 你正在检查哪些资源和权限,不需要实例?添加一个新的“公司”?编辑公司的权限需要公司本身。如果是添加,那么你可以选择走资源路线并传入一个新的Company(),或者你有像CompanyPermission声明这样的东西,并在其中放置CRUD类型的权限,然后在公司控制器上使用声明检查策略来检查用户是否具有任何公司访问权限,然后进一步在每个控制器方法中进行深入检查。 - blowdart

0

ClaimsPrincipalPermission在aspnet 5中不可用。 - Gillardo
在asp.net core中,您无法实现自己的AuthorizeAttribute。该属性不包含代码。 - blowdart

-2

ASP.NET提供开箱即用的身份验证机制,非常易于使用,例如:

public class HomeController : Controller
{
    [Authorize]
    public ActionResult Index()
    {
        ViewBag.Message = "This can be viewed only by authenticated users only";
        return View();
    }

    [Authorize(Roles="admin")]
    public ActionResult AdminIndex()
    {
        ViewBag.Message = "This can be viewed only by users in Admin role only";
        return View();
    }
}

查看本教程

或者,如果您想要更复杂的机制,可以基于ASP.NET成员资格提供程序实现自己的成员资格提供程序。


这与asp.net5无关,而且角色(组)是动态的。 - Gillardo
这是 .NET 框架的一部分,适用于 Web 应用程序,您可以在任何 .NET 版本中使用它,更重要的是,我向您保证它可以完成您最初在问题中提出的要求。 - Fourat
@Fourat 不,这样做不行。如果角色是动态的,那么这就不符合问题的要求。你已经硬编码了admin角色可以访问AdminIndex。这不是动态的。 - mason
@mason 请阅读教程,Authorize属性需要一个Roles参数,它是一个字符串,你可以硬编码这个字符串,从XML中获取它,将其加载到可枚举对象中,或者从数据库中获取...这取决于你。 - Fourat
你的回答中没有展示如何使其动态化。我也不认为这是使用内置属性实现的可能性。你会收到一个错误提示:属性参数必须是常量表达式、typeof 表达式或属性参数类型的数组创建表达式。 - mason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接