クライアントリクエストに従うように、サービス側のクレームタイプ要件を指定するにはどうすればよいですか?
-
01-10-2019 - |
質問
私は持っています:
- IDプロバイダーでもあるパッシブSTS「ログインアプリケーション」。
- Actasトークンを受け入れて処理できるアクティブなSTS WCFサービス
- パーティーに依存するWebサイト
- Webサイトで呼ばれるWCFサービスに依存しています。
これらはすべて、Windows Identity FoundationとCustom STSコードを使用してまとめられています。 Active Directory(ADFS)は関与していません。
私が今働いているのは:
- ユーザーはWebサイトRPにアクセスしようとします。
- ユーザーはパッシブSTにリダイレクトされます。
- ユーザーログイン、トークンが発行され、WebサイトRPにリダイレクトされます。
- WebサイトRPは、WCF RPへのサービスコールを行い、Actasトークンに合格して代表団が発生します。
- Active STSはActasトークンが入ってきて、出力アイデンティティを適切にセットアップするため、主要なアイデンティティはActasトークンであり、発信者のアイデンティティがアクターチェーンに追加されます。
- WCF RPは、すべての状態に適切なトークンを取得し、現在のスレッドプリンシパルには正しいアイデンティティと主張があります。
WCF RPにアクティブなSTSから追加のクレームを要求してもらいたいです。
つまり、アクティブなSTSに行く最初の条件では、サービスが必要とするクレームのリストを含めて、それらがまだ存在していない場合、それらの追加のクレームを取得できるようにしたいと思います。
WebサイトRPクライアントのバインディングを変更することでこれを行う方法を考え出しましたが、WCF RPサービスエンドで要件を指定したいと考えています。
私はそれが私が使用しているバインディングと関係があると感じています。 WS2007FEDERATIONHTTPBINDINGを使用するのに苦労しました。ACTASトークンとWIF IDトレーニングキットのすべての例を使用してカスタムバインディングを使用したため、それを行いました。これは、私のバインディング構成を示すWCF RPの構成スニペットです。
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinding_FederatedService">
<security
authenticationMode="IssuedTokenForCertificate"
messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10">
<issuedTokenParameters tokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
<issuer address="http://localhost:38901/ActiveSts.svc/IWSTrust13" />
<issuerMetadata address="http://localhost:38901/ActiveSts.svc/mex" />
</issuedTokenParameters>
</security>
<textMessageEncoding>
<readerQuotas maxArrayLength="32767" />
</textMessageEncoding>
<httpTransport />
</binding>
</customBinding>
</bindings>
</system.serviceModel>
発行済みのWebサイトのCONFIGを変更して、発行されたTokenParametersセクションで請求視点を示す場合、アクティブSTSは実際にRSTの必要なクレームのリストを表示します...しかし、それは私にとって問題のある呼び出しのWebサイトにあります。
WCF RPが、通話Webサイトでその構成を複製することなく、必要な追加のクレームを指定できるようにするにはどうすればよいですか?
それが実際に拘束力のある問題である場合、私が上記のものを考えると、同等の構成を私に示すことができればそれは助けになります。適切な変更でWebサイトとWCFサービスを更新できますが、繰り返しますが、必要なクレームのリストを制御するために、サービス(またはサービスの動作、またはサービスの構成)が必要です。サービスは、欠落している要求を受け入れてはなりません。
解決
あなたがこれをしなければならない方法は...
- STSのトークンリクエストを手動で作成します。 Microsoft.IdentityModelを使用するのではなく
CreateChannelActingAs(token)
拡張方法、手動でActasトークン(または新しいトークン)を使用してリクエストしますWSTrustChannelFactory
. - 手動で要求されたトークンを発信チャネルパラメーターに追加します。
これにより、クライアントが請求要件のリストについて知る必要性を正確に削除するわけではありませんが、その構成を何らかの形で集中化することができたり、サービス自体を使用して請求要件のリストを提供することができます。残念ながら、Microsoft.identityModelスタックには、これらすべてを行うものはありません。セキュリティトークンのリクエストはクライアントコミュニケーションの一部として発行され、サービスの運用リクエストが来るときにサービスによって発行されないため、クライアントは請求要件のリストを完全に知る必要があります。
とにかく、あなたはいくつかのまともな説明を見ることができます WSTrustChannelFactory
と WSTrustChannel
MSDN Webサイトで. 。私の解決策はそれに基づいています。
すべてのエラー処理などなしで煮詰められます。コードは基本的に次のようになります。
// You need the channel factory so you can get info about the endpoint.
var factory = new ChannelFactory<IService>();
// Get the issuedTokenParameters information from the binding.
// You see this in the XML config but it's painful to access.
var tokenParameters = factory.Endpoint.Binding
.CreateBindingElements()
.OfType<SecurityBindingElement>().First()
.EndpointSupportingTokenParameters
.Endorsing.OfType<IssuedSecurityTokenParameters>().First();
// Prepare the RST.
var trustChannelFactory = new WSTrustChannelFactory(tokenParameters.IssuerBinding, tokenParameters.IssuerAddress);
var trustChannel = (WSTrustChannel)trustChannelFactory.CreateChannel();
var rst = new RequestSecurityToken(RequestTypes.Issue);
rst.AppliesTo = factory.Endpoint.Address;
// If you're doing delegation, set the ActAs value.
var principal = Thread.CurrentPrincipal as IClaimsPrincipal;
var bootstrapToken = principal.Identities[0].BootstrapToken;
rst.ActAs = new SecurityTokenElement(bootstrapToken);
// Here's where you can look up claims requirements dynamically.
rst.Claims.Add(new RequestClaim("http://dynamically-added-claim"));
// Get the token and attach it to the channel before making a request.
RequestSecurityTokenResponse rstr = null;
var issuedToken = trustChannel.Issue(rst, out rstr);
var fccParameters = new FederatedClientCredentialsParameters();
fccParameters.IssuedSecurityToken = issuedToken;
var channel = factory.CreateChannel();
((IChannel)channel).GetProperty<ChannelParameterCollection>().Add(fccParameters);
// NOW you can make the request.
channel.DoWork();
これにより、システムの周りに流れる通信の一部を最適化することを望んでいる場合、トークンを発行するキャッシュをキャッシュすることもできます。
確かに、クレーム要件を動的に挿入しようとしていない場合、またはXML構成を使用してサーバーとクライアントで複製することを満足させない場合は、これは必要ありません。 CreateChannelActingAs(token)
拡張法とMicrosoft.IdentityModelスタック全体がこれを処理します。