【问题标题】:How to exchange an authorization token on the server side如何在服务器端交换授权令牌
【发布时间】:2018-10-03 22:40:55
【问题描述】:

我有一个使用 OAuth 身份验证的 ASP.Net Core 2.1 Web API。此外,我们使用基于声明的身份验证,声明编码在身份验证令牌中。

这已经有一段时间了,但最近当一个新要求出现时,事情已经失控了,这从根本上增加了必须存储在令牌中的声明数量。长话短说,我们现在处于身份验证令牌如此长的地步,以至于我们不得不重新配置我们的服务器以允许超过 128k 的标头。

这显然是站不住脚的;仅从网络流量的角度来看,必须发送超过 100k 的标头以及最简单的 GET 请求是荒谬的。所以现在我正在考虑以下思路:不要在令牌中编码声明,只需使用 Guid 令牌并将声明与令牌一起存储在 database 中,所以当我们验证令牌时我们可以同时提取索赔并在本地交换。

理论上这应该一举解决我们的整个问题,但我只是停留在实现细节上,特别是:由于基于声明的身份验证期望找到编码在身份验证令牌中的声明,我该如何交换取出包含所有声明的 Guid 身份验证令牌?

现有代码:

public class MyAuthenticationEvents : OAuthValidationEvents
{
    public override async Task ValidateToken(ValidateTokenContext context)
    {
        if (context.Properties.ExpiresUtc < DateTime.UtcNow)
        {
            context.Fail("Access Token has expired.");
            return;
        }
        if (!await TokenIsValidAsync(context)) // code to validate the auth token against the database, could be modified to return claims
        {
            context.Fail("Access Token has not been properly set or has been invalidated.");
            return;
        }
        // Here I would expect to do some skullduggery to switch the compact Guid token for a large token containing claims
        context.Success();
    }
}

什么是正确的语法?还是我找错人了,有更好的方法来实现我的目标?

【问题讨论】:

    标签: asp.net-core oauth-2.0 asp.net-core-2.1


    【解决方案1】:

    结果很简单。在ValidateToken() 方法中,我需要做的就是使用ClaimsIdentity 创建一个新的ClaimsPrincipal,我根据存储在数据库中的序列化声明重建了它:

      ... // create claimsIdentity from serialized claims
      context.Principal = new ClaimsPrincipal(claimsIdentity);
      context.Success();
    }
    

    只需要注意一件事:在初始登录时,必须返回 Subject 声明,因此在 HandleTokenRequest() 方法中我们仍然需要:

    identity.AddClaim(new Claim(OpenIdConnectConstants.Claims.Subject, user.Username));
    

    【讨论】:

      【解决方案2】:

      您现有的身份验证中间件正在根据 JWT 的内容在 ClaimsPrincipal 上填充声明,但是当您的授权处理程序检查声明时,它们并没有直接从令牌中读取,因此无需修改令牌本身。

      您应该能够从中间件访问和修改当前用户 (HttpContext.User) 声明,因此您可以使 custom middleware 在身份验证中间件之后执行并根据数据库查找的结果添加声明。

      编辑:正如 Shaul 在他的回答中指出的那样,这也可以在您的身份验证组件的 Validate 方法中完成。在这种情况下,这实际上是一个好地方。如果您希望将声明从数据库中“翻译”为与身份验证过程分离的声明,则单独的中间件(如我所述)将起作用。关键是 ASP.NET Core 将用户声明存储在 ClaimsPrincipal 对象中,您只需要更新它而不用担心令牌本身。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-29
        • 2021-07-28
        • 2014-07-09
        • 1970-01-01
        • 2017-01-08
        • 2015-06-12
        相关资源
        最近更新 更多