gpt4 book ai didi

.net - .net 中基于资源的授权

转载 作者:行者123 更新时间:2023-12-04 01:05:51 24 4
gpt4 key购买 nike

假设您有一个带有 GetResource(int resourceId) 操作的 .net web api。此操作(具有指定的 id)应该只授权给与该 id 关联的用户(例如,资源可以是用户撰写的博客文章)。

这可以通过多种方式解决,但下面给出一个示例。

    public Resource GetResource(int id)
{
string name = Thread.CurrentPrincipal.Identity.Name;
var user = userRepository.SingleOrDefault(x => x.UserName == name);
var resource = resourceRepository.Find(id);

if (resource.UserId != user.UserId)
{
throw new HttpResponseException(HttpStatusCode.Unauthorized);
}

return resource;
}

用户已通过某种机制的身份验证。

现在,假设我还希望某个用户(例如,管理员类型)被授权使用端点(具有相同的 id)。此用户与资源没有任何直接关系,但由于其类型(或角色)而具有授权。这可以通过检查用户是否为管理员类型并返回资源来解决。

有没有办法以某种方式集中它,这样我就不必在每个操作中编写授权代码?

编辑
根据答案,我认为我必须澄清我的问题。

我真正追求的是某种机制,可以使基于资源的授权成为可能,但同时允许一些用户也使用相同的端点和相同的资源。下面的操作将为这个特定的端点和这个特定的角色(管理员)解决这个问题。
    public Resource GetResource(int id)
{
string name = Thread.CurrentPrincipal.Identity.Name;
var user = userRepository.SingleOrDefault(x => x.UserName == name);
var resource = resourceRepository.Find(id);

if (!user.Roles.Any(x => x.RoleName == "Admin" || resource.UserId != user.UserId)
{
throw new HttpResponseException(HttpStatusCode.Unauthorized);
}

return resource;
}

我追求的是一些通用的方法来解决这个问题,这样我就不必编写两个具有相同目的的不同端点或在每个端点中编写资源特定的代码。

最佳答案

好简单

需求

    public class PrivateProfileRequirement : IAuthorizationRequirement
{
public string ClaimType { get; }

public PrivateProfileRequirement(string claimType)
{
ClaimType = claimType;
}
}

public class PrivateProfileHandler : AuthorizationHandler<PrivateProfileRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PrivateProfileRequirement requirement)
{
if (context.User != null)
{
if (context.User.Claims.Any(c => string.Equals(c.Type, requirement.ClaimType, StringComparison.OrdinalIgnoreCase)))
{
if (context.User.Identities.Any(i => string.Equals(i.GetId(), context.Resource)))
{
context.Succeed(requirement);
}
}
}

return Task.CompletedTask;
}
}

启动.cs
        services.AddAuthorization(options =>
{
options.AddPolicy("PrivateProfileRequirement",
policy => policy
.RequireAuthenticatedUser()
.RequireRole(Role.Profile.ToRole())
.AddRequirements(new PrivateProfileRequirement(ClaimTypes.NameIdentifier)));
});

Controller
public class ProfileController : Controller
{
private readonly IAuthorizationService _authorizationService;

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

行动
public async Task<IActionResult> OnGetAsync(int id)
{
var profile = _profileRepository.Find(id);

if (profile == null)
{
return new NotFoundResult();
}

var authorizationResult = await _authorizationService
.AuthorizeAsync(User, profile.Id, "PrivateProfileRequirement");

if (authorizationResult.Succeeded)
{
return View();
}

return new ChallengeResult();
}

关于.net - .net 中基于资源的授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18854434/

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