0

我用谷歌搜索了这个并没有找到任何东西,所以我想知道那些使用 DotNet Core 时间比我自己更长的人。

我现在到了 DotNet 核心。我目前正在创建一个应用程序只是为了练习。我注意到在我的大多数 API 操作中,我正在根据声明 NameIdentifier(即登录的用户 ID)验证传入的 UserId。

我正在这样做:

        if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
        {
            return Unauthorized();
        }

但现在想想,它变得有点过于重复了。有没有办法使用属性代替?

就像是:

    [AuthorizeUser(UserId = userid)]
    [HttpGet]
    public async Task<IActionResult> GetSomething(int userId)
    {
            //Custom code ...
    }

然后创建我的授权属性:

public class AuthorizeUser : AuthorizeAttribute, IAuthorizationFilter
{
    public AuthorizeUser(params string[] args)
    {
        Args = args;
    }

    public string[] Args { get; }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        //Custom code ...
    }
}

这样,我将在一个地方为我的所有操作检查在“api/user/{userId}”中传递的用户 ID。

或者还有另一种方法可以让我的代码看起来更好,并且复制和粘贴更少?

先感谢您。

4

1 回答 1

0

我能够通过执行以下操作来解决我的问题:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class UserAuthorizationAttribute : AuthorizeAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        // Here I can get userId from my params.
        var userId = context.RouteData.Values["userId"].ToString();

        // It is then being checked against current user claims.
        // The user is only authorized if the userId is equals to ClaimsType.Value and claims Type is equals to NameIdentifier. 
        var isUserAuthorized = context.HttpContext.User.Claims.Any(c => c.Type == ClaimTypes.NameIdentifier && c.Value == userId);
        
        if (!isUserAuthorized)
        {
            context.Result = new UnauthorizedResult();
        }
    }
}
于 2020-07-31T13:25:05.907 回答