我有一个使用WIF和.NET 4.5实现的基于声明的身份验证系统的工作实现。它包含通常的部分:
从前端应用程序到支持的WCF服务的调用使用Delegated身份验证,因此用户在前端应用程序中进行身份验证,应用程序请求具有ActAs = BootstrapToken的新令牌,然后调用WCF服务。
这一切都与SAML令牌一起正常工作。
现在我想使用JWT令牌与WebApi通信,所以我在我的STS和WebApi项目中安装了JSON Web Token Handler For the Microsoft .Net Framework 4.5 Nuget包。
所以我让我的STS正确签发了签名的JWT令牌,我的WebApi依赖方验证了相同的令牌。一切都很好。
问题:
如果我在RST的ActAs字段中使用JWT令牌,它将被发送没有签名,因此它自然会被STS拒绝。似乎SecurityTokenHandler.ReadToken()方法返回的令牌返回没有任何签名信息的令牌。
现在我的困境是:这是JWT令牌支持的场景吗?据我所知,JWT令牌不包含验证签名的所有信息,而不是SAML令牌,那么还有其他限制吗?
另一方面,如果确实支持这个,有没有人以前实现过这个,或者有任何想法?这是一个开发者预览版,所以它可能是一个错误吗?
修改的
这是一个说明问题的示例。在STS(可访问签名密钥)和依赖方(可访问证书的公钥)中运行时,代码会产生相同的结果:
System.Diagnostics.Debug.WriteLine("Raw Token : {0}", (object)rawToken);
var readToken = this.identityConfiguration.SecurityTokenHandlers.ReadToken(rawToken);
this.identityConfiguration.SecurityTokenHandlers.ValidateToken(readToken);
var serializedToken = this.identityConfiguration.SecurityTokenHandlers.WriteToken(readToken);
System.Diagnostics.Debug.WriteLine("Serialized Token: {0}", (object)serializedToken);
制作以下内容
Raw Token : eyJAi(...)x3a9.eyJvYXB(...)DYzWiJ9.y-lT(...)PyBUTw
Serialized Token: eyJAi(...)x3a9.eyJvYXB(...)DYzWiJ9.
因此,显然,读/写往返丢失了签名信息。我能理解为什么这会在RP中发生,而不是在STS中发生。
编辑2
所以这是当前的JWTSecurityTokenHandler.WriteToken(SecurityToken token)
实现:
public override string WriteToken(SecurityToken token)
{
Utility.VerifyNonNullArgument("token", token);
JWTSecurityToken jWTSecurityToken = token as JWTSecurityToken;
if (jWTSecurityToken == null)
{
throw new SecurityTokenException(string.Format(CultureInfo.InvariantCulture, "JWT10200: This instance of JWTSecurityTokenHandler can only write SecurityTokens of type '{0}', a SecurityToken of type '{1}' was received.", new object[]
{
typeof(JWTSecurityToken),
token.GetType()
}));
}
string text = string.Empty;
string text2 = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", new object[]
{
jWTSecurityToken.EncodedHeader,
jWTSecurityToken.EncodedPayload
});
if (jWTSecurityToken.SigningCredentials != null)
{
text = this.Sign(text2, jWTSecurityToken.SigningCredentials);
}
return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", new object[]
{
text2,
text
});
}
通过调查,很明显,在RP中,书面令牌永远不会有签名,因为我们没有签名证书。所以这看起来不像是一个bug,而是一个实现决策。我只是不明白为什么。
由于
答案 0 :(得分:3)
这既不是安全性(或任何其他)错误,也不是实施决策。 Write可以生成带签名的JWT的唯一位置是发布点。 除了令牌发行者之外的任何一方都不应该尝试重新创建它(这就是读写往返的意思)。 当您收到签名的JWT时,您只能验证并阅读它。您可以按原样重新传输原始JWT,但由于您不是发行人而且没有相应的签名密钥,您将无法“正确”重建它。
这是签署令牌背后的原因:只有原始发行人才能正确签名。
如果您愿意,我可以尝试帮助您使用安全令牌和STS设计正确的方案,但为此,请分享您正在实施的方案的序列图。
答案 1 :(得分:2)
如果这是一个错误,我不会感到惊讶 - JWT处理程序仍处于预览模式。
但也许你不想为Web API服务做全面的ActAs - 看看这里:
答案 2 :(得分:0)
查看JWTSecurityToken.RawData。那包含原始的encodedToken。并且应该有原始发行人的签名。