gpt4 book ai didi

asp.net-core - 具有自定义要求/处理程序的 .Net Core 授权

转载 作者:行者123 更新时间:2023-12-04 01:47:21 25 4
gpt4 key购买 nike

我之前问过类似的问题,并在其他人的帮助下取得了一些进展,但仍然不确定我在这里做错了什么或错过了什么。

我的应用程序有点简单:
域用户通过身份验证。
经过身份验证的用户(作者)创建一个请求,保存在数据库中。
其他经过身份验证的用户只能查看请求。
作者和管理员用户可以编辑/删除请求。

这是我遵循的示例之一:
Different API functionality for different roles

另一个PoliciesAuthApp:https://github.com/aspnet/Docs/tree/master/aspnetcore/security/authorization/policies/samples/PoliciesAuthApp1
我不确定如何在此处使用/注册/调用 PermissionHandler。

这是我的代码:

Startup.cs

//  Add Authentication
// Global filter
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireRole("Role - Domain Users")
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});


// Add Authorization Handlers
services.AddAuthorization(options =>
{
options.AddPolicy("EditPolicy", policy => policy.Requirements.Add(new EditRequirement()));
});

services.AddSingleton<IAuthorizationHandler, PermissionHandler>();

EditRequirement.cs
public class EditRequirement : IAuthorizationRequirement
{
}

PermissionHandler.cs
public class PermissionHandler : IAuthorizationHandler
{

public Task HandleAsync(AuthorizationHandlerContext context)
{
var pendingRequirements = context.PendingRequirements.ToList();

foreach (var requirement in pendingRequirements)
{
if (requirement is ReadRequirement)
{
if (IsOwner(context.User, context.Resource) ||
IsAdmin(context.User, context.Resource))
{
context.Succeed(requirement);
}
}
else if (requirement is EditRequirement ||
requirement is DeleteRequirement)
{
if (IsOwner(context.User, context.Resource) || IsAdmin(context.User, context.Resource))
{
context.Succeed(requirement);
}
}
}
return Task.CompletedTask;
}

private bool IsAdmin(ClaimsPrincipal user, object resource)
{
if (user.IsInRole("Role - Administrator"))
{
return true;
}
return false;
}

private bool IsOwner(ClaimsPrincipal user, object resource)
{
if (resource is CreateRequestViewModel)
{
var ctx = (CreateRequestViewModel)resource;

if (ctx.RequestEnteredBy.Equals(user.Identity.Name))
{
return true;
}
}
else if (resource is AuthorizationFilterContext)
{
var afc = (AuthorizationFilterContext)resource;

// This is not right, but I don't know how to deal with AuthorizationFilterContext
// type passed into resource parameter when I click Edit button trying to edit the request
if (afc.HttpContext.User.Identity.Name.Equals(user.Identity.Name))
{
return true;
}
}
else if (resource is Request)
{
var r = (Request)resource;

if (r.RequestEnteredBy.Equals(user.Identity.Name))
{
return true;
}
}


return false;
}

private bool IsSponsor(ClaimsPrincipal user, object resource)
{
// Code omitted for brevity

return true;
}
}

RequestsController.cs
private IAuthorizationService _authorizationService;

public RequestsController(ApplicationModelContext context, IAuthorizationService authorizationService)
{
_context = context;
_authorizationService = authorizationService;
}

[Authorize(Policy = "EditPolicy")]
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}

CreateRequestViewModel crvm = new CreateRequestViewModel();

var request = await _context.Request
.SingleOrDefaultAsync(m => m.RequestId == id);

if (request == null)
{
return NotFound();
}

var authorizationResult = await _authorizationService.AuthorizeAsync(User, request, "EditPolicy");

if (authorizationResult.Succeeded)
{
// Load request contents and return to the view

return View(crvm);
}

// This needs to be changed to redirect to a message screen saying no permission
return RedirectToAction("Details", new { id = request.RequestId });
}

在调试应用程序时,我发现:
  • 页面第一次从数据库加载请求时,通过
    一个 CreateRequestViewModel 类型对象的资源参数
    PermissionHandler 中的 IsOwner 方法。
  • 点击页面上请求项的编辑按钮后,通过
    AuthorizationFilterContext 类型
  • 然后进入 ReuqestController 中的 Edit 操作,它发送一个
    请求类型(在 _authorizationService.AuthorizeAsync 中)。

  • 不确定我是否做了重复或完全混合不同方法的事情。

    任何建议将不胜感激。

    最佳答案

    看起来您正在混合基于策略和资源的授权。基于资源的听起来像您想要的,因为您可能不想为每个 CRUD 操作创建策略,即“CreateUserPolicy”、“UpdateUserPolicy”,然后将不同的要求传递给每个操作。
    有关基于资源的授权,请参阅本教程:https://docs.microsoft.com/en-us/aspnet/core/security/authorization/resourcebased?view=aspnetcore-2.2

    为了对用户资源进行授权,我创建了一个 UserAuthorizationHandler:

    启动.cs:

    services.AddScoped<IAuthorizationHandler, UserAuthorizationHandler>();

    UserAuthorizationHandler.cs
    public class UserAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, User>
    {
    private readonly IPermissionRepository _permissionRepository;

    public UserAuthorizationHandler(IPermissionRepository permissionRepository)
    {
    _permissionRepository = permissionRepository;
    }

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, OperationAuthorizationRequirement requirement, User resource)
    {
    var authUserId = int.Parse(context.User.FindFirstValue(ClaimTypes.NameIdentifier));

    if (requirement == AuthorizationOperations.Create)
    {
    if (await CanCreate(authUserId))
    {
    context.Succeed(requirement);
    }
    }
    else if (requirement == AuthorizationOperations.Read)
    {
    if (await CanRead(authUserId, resource))
    {
    context.Succeed(requirement);
    }
    }
    }

    /// <summary>
    /// User can create if they have 'create' 'users' permission.
    /// </summary>
    /// <param name="authUserId">The requesting user</param>
    /// <returns></returns>
    public async Task<bool> CanCreate(int authUserId)
    {
    return await _permissionRepository.UserHasPermission(authUserId, "create", "users");
    }

    /// <summary>
    /// User can read if reading themselves or they have the 'read' 'users' permission.
    /// </summary>
    /// <param name="authUserId">The requesting user</param>
    /// <param name="user">The requested resource</param>
    /// <returns></returns>
    public async Task<bool> CanRead(int authUserId, User user)
    {
    return authUserId == user.Id || await _permissionRepository.UserHasPermission(authUserId, "read", "users");
    }
    }

    Controller :
      var authorized = await _authorizationService.AuthorizeAsync(User, new User { Id = id}, AuthorizationOperations.Read);
    if (!authorized.Succeeded)
    {
    return Unauthorized();
    }

    关于asp.net-core - 具有自定义要求/处理程序的 .Net Core 授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54789857/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com