如果服务可以访问 DNN 数据库,那么您可以使用引用代码实现的验证。
似乎这些令牌不是真正的JWT 令牌,因为它们是自包含的,尽管它们也不是真正的参考令牌。令牌保留在数据库中,但也包含公共数据。
这是如何实现的:令牌由sessionId标识,秘密是一个连接的字符串,转换为字节数组:
var secret = ObtainSecret(sessionId, portalSettings.GUID,
userInfo.Membership.LastPasswordChangeDate);
数据是JWT。它包含一个标头、一个有效负载和一个签名。
从收到的令牌首先验证标头(和方案)。然后读取 RAW 令牌,验证过期并检查 SessionId 的存在,将其添加为声明 (TokenId)。
最后一步是使用 SessionId 从存储(缓存/数据库)中查找用户:
private UserInfo TryGetUser(JwtSecurityToken jwt, bool checkExpiry)
{
// validate against DB saved data
var sessionId = GetJwtSessionValue(jwt);
var ptoken = DataProvider.GetTokenById(sessionId);
未找到 SessionId 时,令牌无效。再次验证过期。
最后将接收到的数据与持久化令牌进行比较,第 423 行:
if (ptoken.TokenHash != GetHashedStr(jwt.RawData))
这应该可以防止令牌被篡改。
这意味着您可以为您的微服务使用相同的代码,前提是这些服务可以访问 DNN 数据库。调用ValidateToken(),它会在有效时返回用户名,在无效时返回null。
另一种方法是像我在这里描述的那样发布您自己的 JWT 令牌。您可以创建中央 API 或使用固定的共享密钥。例如,可用于微服务的证书。在这种情况下,您正在处理可以使用默认验证器验证的自包含 JWT 令牌。而且您不需要访问数据库。