WIF と .NET 4.5 で実装されたクレーム ベースの認証システムの実用的な実装があります。通常の部分が含まれています:
- パッシブおよびアクティブ エンドポイントを使用したカスタム STS
- バックエンド WCF サービス
- フロントエンド MVC アプリケーション
- フロントエンド WebApi アプリケーション
フロントエンド アプリケーションから backedn WCF サービスへの呼び出しでは委任認証が使用されるため、ユーザーはフロントエンド アプリで認証され、アプリは ActAs=BootstrapToken を使用して新しいトークンを要求し、WCF サービスを呼び出します。
これはすべて、SAML トークンで正しく機能しています。
ここで、JWT トークンを使用して WebApi と通信したいので、STS および WebApi プロジェクトにMicrosoft .Net Framework 4.5 Nuget パッケージの JSON Web Token Handlerをインストールしました。
そのため、STS が署名付き JWT トークンを正しく発行し、WebApi Relying Party が同じトークンを検証しています。大丈夫だ。
問題:
RST の ActAs フィールドで JWT トークンを使用すると、署名なしで送信されるため、当然 STS によって拒否されます。SecurityTokenHandler.ReadToken() メソッドによって返されるトークンは、署名情報なしでトークンを返すようです。
今、私のジレンマはこれです: これは JWT トークンでサポートされているシナリオですか? 私が理解している限り、SAML トークンとは対照的に、JWT トークンは署名を検証するためのすべての情報を持っていないので、他に制限はありますか?
一方、これが実際にサポートされている場合、これを以前に実装した人やアイデアはありますか? これは開発者向けプレビューなので、バグでしょうか?
編集
これは、問題を説明するためのサンプルです。このコードは、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 にある場合は署名がないことは明らかです。したがって、これはバグではなく、実装上の決定のようです。理由がわかりません。
ありがとう