我做了很多研究,但我仍然不确定我是否正确地做了这件事。 我找到的最好的资源是
http://leastprivilege.com/2015/10/12/the-state-of-security-in-asp-net-5-and-mvc-6-authorization/
鉴于ApplicationUser类已扩展为包含授权帐号列表,我希望将用户限制为仅在其授权帐户上查看语句(以及其他基于操作)。我认为这是一个非常常见的设计,但网上的大多数文章都提到了以前版本的身份。
(PS我在Controller构造函数中注入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();
}
我不能帮助感觉有更好的方法吗? 基本上我想基于action参数进行授权。“accountNo”
有关采取何种方法的任何提示。
答案 0 :(得分:3)
在这种情况下,您将使用基于资源的帐户作为资源。相关文档位于https://docs.asp.net/en/latest/security/authorization/resourcebased.html
首先,您要定义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);
}
}
之后在配置服务中的DI容器中注册您的策略;
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthorization();
services.AddSingleton<IAuthorizationHandler,
AccountAuthorizationHandler>();
}
在您的控制器中注入AuthorizationService;
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();
}
}
答案 1 :(得分:0)
如果您希望以允许您将其用于UIViewContentModeScaleAspectFill
属性的方式定义授权策略,则可以更改Apple docs所见的方法:
[Authorize]
这样做的缺点是,您需要确保使用该属性的所有操作以一致的方式执行,即每次使用相同的action参数或路由参数名称。
@ blowdart在控制器操作中使用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'
});
});
});
的示例演示了一种使用和重用策略的方法,该策略允许参数名称与策略本身分离。虽然我们可以看到IAuthorizationService
没有提供强类型泛型方法,但它似乎提供了一种不太脆弱的方法来实现基于资源的策略。