【问题标题】:Correct way to support multiple authorization attributes on ASP.Net Web API 2在 ASP.Net Web API 2 上支持多个授权属性的正确方法
【发布时间】:2019-05-16 19:57:46
【问题描述】:

我的 ASP.Net Web API 应用程序在成功登录后创建了一个 JWT 令牌。

public IHttpActionResult LogOn([FromBody] LoginRequest request)
    {
        var result = _service.LogOn(request);
        if (result.Success)
        {
            var token = CreateToken(request.UserName);
            return Ok(OpResult<string>.SuccessResult(token));
        }

        return Ok(result);
    }

我的所有控制器方法都装饰有“Authorize”属性,该属性委托给我的 TokenValidationHandler(继承自 DelegatingHandler)以在后续请求中验证令牌。

[HttpGet]
[Authorize]
public IHttpActionResult GetAccount(){ // get user details here}

现在我有一个要求,除非他们创建了一个帐户并验证了他们的电子邮件地址,否则不要让用户进入。所以我的想法是,在第一种方法(用户登录)中,我不仅要检查 result.success 并发出令牌,还要检查检索到的帐户是否经过电子邮件验证。如果不是,我会发出一个 jwt 令牌,其中附加声明“emailverified”设置为 false。因此,尚未激活电子邮件的用户仍然可以登录并获取此 jwt 令牌,但他们唯一被允许的操作是验证电子邮件。

如何实现这个 VerifyEmail 控制器方法?理想情况下,我希望它如下所示

[HttpGet]
[AuthorizeEvenIfEmailNotVerified]
public IHttpActionResult GetAccount()

如何实现 AuthorizeEvenIfEmailNotVerified ?它是从 DelegatingHandler 继承的另一个处理程序吗?但是,如果我有两个这样的处理程序(我现有的用于常规授权的处理程序和这个新的处理程序),那么 ASP.Net 引擎如何知道将 [Authorize] 属性发送到哪个处理程序以及将 [AuthorizeEvenIfEmailNotVerified] 发送到哪个处理程序? 或者我应该使用 AuthenticationFilter 吗? 但在那种情况下,我有两个属性做几乎相同的事情似乎很奇怪(一个验证经过验证的用户,另一个验证未验证的用户)。然而其中一个是通过由继承 DelegatingHandler 的处理程序支持的 [Authorize] 实现的,而另一个是通过 AuthenticationFilter 支持的属性实现的?

或者我是不是走错了路?作为记录,除非绝对需要,否则我宁愿让项目不包含任何与 MVC 相关的库。这也是 .Net Framework 4.7 项目。

【问题讨论】:

  • 如果电子邮件得到确认,令牌的发行者也应该“担心”。也许像 ValidEmail 这样为 jwt 添加一个范围,这样您的 MVC 应用程序就可以通过向您的数据库添加额外调用来检查令牌。
  • 是的,如果电子邮件被确认,发行人会担心。这就是我说“不仅仅是检查 result.success 并发出令牌,我还要检查检索到的帐户是否经过电子邮件验证。如果不是,我会发出一个带有附加声明的 jwt 令牌“电子邮件验证”设置为假”
  • 我的问题是如何实现像 verifyemail 或 resendverification 这样的方法,只有当请求带有我发出的这个令牌时,我才想允许这两种方法。显然我不能用“[Authorize]”标记它们,因为这会导致我完全验证的登录处理程序处理不是我想要的请求。我希望用一个属性来装饰这些方法,该属性调用一个备用令牌处理程序,该处理程序验证令牌是否有效并将声明“emailverified”设置为 false”

标签: c# authentication asp.net-web-api asp.net-web-api2 asp.net-web-api-routing


【解决方案1】:

角色可能是最简单的解决方案。生成具有相关声明的令牌:

identity.AddClaim(new Claim(ClaimTypes.Role, "Verified")); //verified email
identity.AddClaim(new Claim(ClaimTypes.Role, "NotVerified")); //not verified email

接下来给控制器添加属性:

[Authorize(Roles="NotVerified")]

【讨论】:

    猜你喜欢
    • 2020-04-11
    • 2018-07-01
    • 2013-06-20
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2018-08-19
    相关资源
    最近更新 更多