如何检查经过身份验证的用户是否具有特定声明且路由段是否与UserId相同?

时间:2018-04-28 06:38:25

标签: authentication asp.net-core attributes middleware claims

我正在尝试在ASP.NET-Core 2 Web应用程序中查看是否可以,如果用户在请求中进行了身份验证,我们还可以检入一些Filter / ActionMethod属性:

  • 他们有特定的声明
  • 该路线包含string id段(例如HttpPut[("{id}")]),且id段需要与Auth'd用户的ID匹配。
  • 请求包含一个带有bearer token的JWT标头,用于“创建”Authenticated Identity(100%正常工作)。

e.g。

  • HTTP PUT /accounts/PureKrome |用户Id:PureKrome |声称:不​​相容。 =>可以继续。 [你正在更新自己。更新自己时不需要任何特殊声明]。
  • HTTP PUT /accounts/PureKrome |用户是匿名或Id:SomethingElse |声明:irrelivant =>失败(禁止回复)[其他人正在尝试更新您,并且没有正确的压倒性声明。所以失败]
  • HTTP PUT /accounts/SomeoneElse |用户是Id:PureKrome |声明:正确的声明。 =>可以继续[尝试更新其他用户,但你有一个允许你这样做的声明]

现在,我在我的ActionMethod代码中执行此操作...首先要做的事情之一。所以我很想知道是否可以使用装饰ActionMethod的属性来实现这一点。

喝彩!

1 个答案:

答案 0 :(得分:1)

这实际上并不太复杂。您需要做的只是authorization filter查看路由值,然后与当前用户一起检查。

像这样简单的东西应该可以正常工作:

public class ValidateUserIdRouteAttribute : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var user = context.HttpContext.User;
        var requestedUserId = context.RouteData.Values["id"] as string;
        var currentUserId = user.FindFirstValue(ClaimTypes.NameIdentifier);

        if (requestedUserId != currentUserId &&
            !user.HasClaim(c => c.Type == "may-edit" && c.Value == requestedUserId))
        {
            context.Result = new UnauthorizedResult();
        }
    }
}

在路线上使用它看起来像这样:

[ValidateUserIdRoute]
[HttpGet("/account/update/{id}")]
public IActionResult UpdateAccount(string id)
{
    // …
}

这就是全部。如果您正确设置了身份验证,则将使用Bearer令牌对可能正确设置或可能未正确设置声明的用户进行身份验证,然后您只需检查这些声明,以查看是否允许访问路由。

当然,您可以扩展这个想法,并为其添加更多功能,例如支持不同的路由数据密钥或类似的东西。