结果你要做的就是…
-
找出一种在客户端检索索赔要求的方法。这可以是某种中央配置服务、WS-Policy/Metadata交换,或者您喜欢的任何类型。
-
手动创建STS的令牌请求。而不是使用Microsoft.IdentityModel
CreateChannelActingAs(token)
扩展方法,使用
WSTrustChannelFactory
.
-
将手动请求的令牌添加到传出通道参数。
请注意,这并不能完全消除客户机了解索赔要求列表的需要,但它确实使您能够以某种方式集中配置,甚至可以使用服务本身来提供索赔要求列表。不幸的是,Microsoft.IdentityModel堆栈中没有任何东西可以为您完成所有这些工作。客户机绝对需要知道索赔要求列表,因为安全令牌请求是作为客户机通信的一部分发出的,而不是作为服务操作请求传入时由服务发出的。
不管怎样,你可以看到一些关于
WSTrustChannelFactory(WSTrustChannelFactory)
和
WSTrustChannel
on the MSDN web site
. 我的解决方案就是基于这个。
在没有所有错误处理等的情况下,代码基本上是这样的:
// 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(令牌)
扩展方法和整个Microsoft.IdentityModel堆栈将为您处理此问题。