【发布时间】: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