将ADFS令牌从客户端发送到WCF服务
问题描述:
我有一个需求,在我的Silverlight应用程序需要连接到WCF服务以通过与Silverlight位于同一个域中的中间WCF服务来获取数据。也就是说,Silverlight将打电话给中间服务,中间服务会将IssuedToken和请求一起附加到中间服务,并将其发送给主WCF客户端。主WCF服务将从Thread.Principal检索声明。将ADFS令牌从客户端发送到WCF服务
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.EstablishSecurityContext = false;
var factory = new ChannelFactory<IMyService>(binding, new EndpointAddress("https://myservice.cloudapp.net:4432/MyService.svc"));
var channel = factory.CreateChannelActingAs(((ClaimsIdentity)((ClaimsPrincipal)HttpContext.Current.User).Identity).BootstrapToken);
var data = channel.GetData();
但是这段代码失败了。我无法找到有关如何实现此目的的财产文件。任何人都可以帮助我这个。
感谢,
答
您需要: 1. ADFS STS服务相反的身份验证使用 “CreateChannelWithIssuedToken” 获得SecurityToken 2.查询您与通道服务,沿着线:
var token = GetToken();
string uri = SERVICE_URL;
EndpointAddress address = new EndpointAddress(uri);
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.EstablishSecurityContext = false;
_factory = new ChannelFactory<IService>(binding, address);
_factory.ConfigureChannelFactory<IService>();
_factory.Credentials.SupportInteractive = false;
_service = _factory.CreateChannelWithIssuedToken<IService>(token);
用于为gettoken的代码如下所示:
public static SecurityToken GetToken(string username, string password, EndpointAddress federationServiceProxyAddress, EndpointAddress relyingPartyIdentifier)
{
var binding = new UserNameWSTrustBinding
{
SecurityMode = SecurityMode.TransportWithMessageCredential
};
var factory = new WSTrustChannelFactory(binding, federationServiceProxyAddress)
{
TrustVersion = System.ServiceModel.Security.TrustVersion.WSTrust13,
};
factory.Credentials.SupportInteractive = false;
factory.Credentials.UserName.UserName = username;
factory.Credentials.UserName.Password = password;
try
{
var requestSecurityToken = new RequestSecurityToken
{
RequestType = WSTrust13Constants.RequestTypes.Issue,
AppliesTo = relyingPartyIdentifier
};
var channel = factory.CreateChannel();
return channel.Issue(requestSecurityToken);//, out requestSecurityTokenResponse);
}
catch (MessageSecurityException exception)
{
// Invalid username or password
throw new MessageSecurityException(exception.Message, exception);
}
catch (Exception exception)
{
// Unknown error
throw new Exception(exception.Message, exception);
}
finally
{
try
{
if (factory.State == CommunicationState.Faulted)
{
factory.Abort();
}
else
{
factory.Close();
}
}
catch (Exception) { }
}
}
希望这有助于...