Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 身份3 MVC 6中的授权策略_C#_Asp.net Mvc_Asp.net Identity - Fatal编程技术网

C# 身份3 MVC 6中的授权策略

C# 身份3 MVC 6中的授权策略,c#,asp.net-mvc,asp.net-identity,C#,Asp.net Mvc,Asp.net Identity,我做了很多研究,但仍然不确定我是否做得正确。 我找到的最好的资源就在这里 给定一个扩展为包含授权帐号列表的ApplicationUser类,我想限制用户仅查看基于其授权帐号的对账单(和其他操作)。我认为这是一个非常常见的设计,但是网上的大多数文章都提到了以前版本的identity (PS我正在控制器构造函数中注入UserManager) 这是我的行动 public IActionResult GetStatement(int accountNo,DateTime startDate,DateT

我做了很多研究,但仍然不确定我是否做得正确。 我找到的最好的资源就在这里

给定一个扩展为包含授权帐号列表的ApplicationUser类,我想限制用户仅查看基于其授权帐号的对账单(和其他操作)。我认为这是一个非常常见的设计,但是网上的大多数文章都提到了以前版本的identity

(PS我正在控制器构造函数中注入UserManager)

这是我的行动

public IActionResult GetStatement(int accountNo,DateTime startDate,DateTime endDate)
{
    var user = userManager.Users
        .Include(u => u.AuthorisedAccounts)
        .Where(u => u.Id == User.GetUserId())
        .FirstOrDefault();
    if (user.AuthorisedAccounts != null)
    {
        foreach (var account in user.AuthorisedAccounts)
        {
            if (account.AccountNo == accountNo)
                return View(statementService.GetStatement(accountNo, startDate, endDate, 0));
        }
    }
    return HttpUnauthorized();
}
我不禁觉得还有更好的办法? 基本上,我想根据操作参数“accountNo”进行授权


任何关于采取何种方法的提示。

在本例中,您将使用基于资源的方法,帐户就是资源。这方面的文档位于

首先,您需要定义一个Read操作

public static class Operations
{
    public static OperationAuthorizationRequirement Read =
        new OperationAuthorizationRequirement   { Name = "Read" };
}
现在您将拥有AccountAccess的策略

public class AccountAuthorizationHandler : AuthorizationHandler<
    OperationAuthorizationRequirement, Account>
{
    IUserManager _userManager;

    public AccountAuthorizationHandler(IUserManager userManager)
    {
        _userManager = userManager;
    }

    protected override void Handle(AuthorizationContext context,
                                   OperationAuthorizationRequirement requirement,
                                   Account resource)
    {
        // Pull the user ID claim out from the context.User
        var userId = context.User.....
        // Get the current user's account numbers.       
        var user = userManager.Users
            .Include(u => u.AuthorisedAccounts)
            .Where(u => u.Id == userId)
            .FirstOrDefault();
    }

    // Now check if the user's account numbers match the resource accountNumber, and 
    // also check the operation type, in case you want to vary based on create, view etc.
    if (user.AuthorisedAccounts.Contains(resource.AccountId &&
        requirement.Name == "View")
   {
      context.Succeed(requirement);
   } 
}
然后,在控制器中,加载帐户资源后,您将执行以下操作

public async Task<IActionResult> View(int accountId)
{
    Account account = accountManager.Find(accountId);

    if (account == null)
    {
        return new HttpNotFoundResult();
    }

    if (await _authorizationService.AuthorizeAsync(User, account, Operations.Read))
    {
        return View(account);
    }
    else
    {
        return new ChallengeResult();
    }
}
公共异步任务视图(int accountId)
{
Account=accountManager.Find(accountId);
如果(帐户==null)
{
返回新的HttpNotFoundResult();
}
if(wait_authorizationService.authorizationAsync(用户、帐户、操作.读取))
{
返回视图(帐户);
}
其他的
{
返回新的ChallengeResult();
}
}

如果您希望以允许将授权策略用于
[Authorize]
属性的方式定义授权策略,您可以更改所看到的方法:

这样做的缺点是,您需要确保使用该属性的所有操作都以一致的方式执行,即每次对操作参数或路由参数使用相同的名称


@blowdart在控制器操作中使用
IAAuthorizationService
的示例演示了一种使用和重新使用策略的方法,该策略允许参数名称与策略本身分离。虽然我们可以看到,
IAuthorizationService
没有提供强类型的泛型方法,但它似乎提供了一种不太脆弱的方法来实现基于资源的策略。

这看起来很有趣,属性是否类似于[Authorize(“AccessByAccountNumber”)]非常感谢BTW解析请求值的问题通常是它们没有那么有用。资源本身将保存决策的信息,例如文档有一个author字段,这就是为什么我们不推荐该路线。在这种情况下,这是可行的,因为用户对象持有一个账号列表,而不是账户持有一个授权用户列表,这更为典型。很好的一点,一旦你离开了最简单的情况,请求可能就没有你做出决定所需的一切。我没想过。有一件事需要注意——授权不是身份的一部分。这是完全独立的:)好的,今天就实施。我对DI相当陌生,但在本例中,我对
服务.AddInstance(newauthorization.AccountAuthorizationHandler())有问题如果不通过usermanager,我似乎无法实例化它。但我认为授权处理程序对其自己的DI进行了排序?UserManager使用DbContext时是否对Singleton安全?好的,我仍然被卡住了-IAuthorizationHandler只包含句柄而不包含AuthorizationAsync。我已经发送了一封关于user manager的电子邮件。为什么希望处理程序具有Authorize async?您正在将AuthorizationService注入控制器中-看到了吗?是的,我试图将处理程序而不是IAAuthorizationService注入控制器中。对不起。我想我已经读了好几遍刚才从我身边经过的文件了。
public class AccountController : Controller
{
    IAuthorizationService _authorizationService;

    public AccountController(IAuthorizationService authorizationService)
    {
        _authorizationService = authorizationService;
    }
}
public async Task<IActionResult> View(int accountId)
{
    Account account = accountManager.Find(accountId);

    if (account == null)
    {
        return new HttpNotFoundResult();
    }

    if (await _authorizationService.AuthorizeAsync(User, account, Operations.Read))
    {
        return View(account);
    }
    else
    {
        return new ChallengeResult();
    }
}
services.AddAuthorization(options =>
{
    // inline policies
    options.AddPolicy("AccessByAccountNumber", policy =>
    {
        policy.RequireDelegate((context, requirement) =>
        {
            var httpContext = (context as dynamic).HttpContext;

            // Proceed to grab the account number from the request values
            // and compare it against the user object stored in 'context.User'
        });
    });
});