公开服务以从加密的 jwt 令牌获取主体对象,而无需任何安全性

问题描述 投票:0回答:1

我在服务器中加密 jwt 令牌并将其发送到客户端,然后将其存储在两个位置 1- 授权标头和 2- cookie 中,当用户刷新页面时使用 cookie,然后再次放置一个副本一个授权标头用于服务器验证,另一个发送到开放服务以解密并获取主体对象以供客户端 WebAssembly 应用程序授权系统使用。

这个设计有缺陷吗?这个开放服务解密令牌并使主体不安全吗?

[HttpPost("GetUserFromEncryptedToken")]
//[Authorize(Roles = "Administrators")]
public async Task<Client.Infrastructure.Auth.User> GetUserFromEncryptedToken(TokenDTO model)
{            
    var handler = new JwtSecurityTokenHandler();
    var validations = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = _config["Jwt:Issuer"],
        ValidAudience = _config["Jwt:Audience"],
        RequireExpirationTime = true,
        IssuerSigningKey = new SymmetricSecurityKey
            (Encoding.UTF8.GetBytes(_config["Jwt:Key"])),
        TokenDecryptionKey = new SymmetricSecurityKey
            (Encoding.UTF8.GetBytes(_config["Jwt:DecryptionKey"])),
        ClockSkew = TimeSpan.FromMinutes(0),
    };
    ClaimsPrincipal claims = null;
    try
    {
        claims = handler.ValidateToken(model.Token, validations, out var tokenSecure);
        var user = Client.Infrastructure.Auth.User.FromClaimsPrincipal(claims);
        return user;
    }
    catch (Exception ex) { return new Client.Infrastructure.Auth.User(); }            
}
security encryption jwt blazor-webassembly
1个回答
0
投票

首先,这类问题的答案总是“视情况而定”。安全性不是绝对的事情,如果实施不当,安全设计就会失败。

开放从 JWT 返回用户名的服务

将 JWT 发送到“开放”服务意味着两件事:该服务要么经过身份验证,要么未经身份验证。我可能不是,因为如果是,您在其他地方也会遇到相同的身份验证问题。

至少,该开放服务不是批发令牌解密服务,它是一个返回加密 JWT 用户名的 oracle。但额外的网络旅行没有任何价值。您必须相信该服务会返回正确的用户名(客户端无法验证该用户名)。我还要求您将加密密钥提供给基础设施中的另一个系统,从而增加密钥的暴露程度。

这很糟糕,因为加密密钥是对称的。对该开放服务的妥协将允许某人生成有效的 JWT。

所以据我了解,开放服务并不是一个好主意。我想说这增加了复杂性并降低了安全性。摆脱它。

从 JWT 获取用户名

为什么需要访问用户名尚不清楚。由于存在 JWT,用户可能已经通过身份验证,并且您想在主页中说“欢迎回来 {USER}”。

也许您在 JWT 中有您不希望客户端看到的声明,并且出于可扩展性/无状态的原因,您可能无法将它们存储在服务器端。根据情况,我会:

  • 对令牌进行签名但不加密。客户端代码可以从中读取用户名
  • 保持 JWT 加密并将用户名保存在隐藏字段、自定义响应标头中或将其刻录到生成的 HTML 中。

使用cookies

如果可能的话,我宁愿不使用cookie。为此,请在每个响应中发送回

Authorization
标头,并使用客户端 JavaScript 将其放回到请求的
Authorization
标头中。这也有助于密钥轮换,因为使用新密钥对新 JWT 进行签名或加密必须比您必须等待用户再次进行身份验证更快。

+如果您将 Cookie 用于任何用途,您的 Cookie 应该设置

secure
http_only
属性。

钥匙轮换

最后,您的设计应该支持多个密钥,其有效期重叠足以在密钥更改时保持大多数用户登录(也称为密钥轮换)。这意味着服务器必须实现如下逻辑:

  1. 使用当前密钥验证签名
  2. 如果失败,用之前的密钥验证签名
  3. 如果失败,则拒绝访问
© www.soinside.com 2019 - 2024. All rights reserved.