C# 未指定用于在url处与联合身份验证服务通信的绑定
我目前正在使用ADFS作为安全令牌服务。我想将WCF服务与ADF联合。我创建了WCF服务,并使用Federation实用程序添加了ADF的STS引用 为了使用联邦wcf服务,我创建了WPF应用程序并添加了服务引用。我使用以下代码调用了服务apiC# 未指定用于在url处与联合身份验证服务通信的绑定,c#,wpf,wcf,adfs,C#,Wpf,Wcf,Adfs,我目前正在使用ADFS作为安全令牌服务。我想将WCF服务与ADF联合。我创建了WCF服务,并使用Federation实用程序添加了ADF的STS引用 为了使用联邦wcf服务,我创建了WPF应用程序并添加了服务引用。我使用以下代码调用了服务api var client=new SecureWpfApplication.ServiceReference1.Service1Client(); Uri=新的Uri(“http://tempuri.org/"); ICredentials credenti
var client=new SecureWpfApplication.ServiceReference1.Service1Client();
Uri=新的Uri(“http://tempuri.org/");
ICredentials credentials=CredentialCache.DefaultCredentials;
NetworkCredential=credentials.GetCredential(uri,“基本”);
client.ClientCredentials.Windows.ClientCredential=凭证;
client.ClientCredentials.SupportInteractive=false;
客户端.GetData(323);
我收到错误“未指定用于在https://{ADFS server}/ADFS/services/trust/13/usernamemix处与联合身份验证服务通信的绑定”
如何解决这个问题
我创建了wcf服务配置,如下所示
<services>
<service name="SecureWcfService.Service1" behaviorConfiguration="SecureWcfService.ServiceBehaviour">
<endpoint address="https://wcfserver/SampleWcfService/Service1.svc" binding="ws2007FederationHttpBinding" contract="SecureWcfService.IService1" bindingConfiguration="SecureWcfService.IService1_ws2007FederationHttpBinding" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SecureWcfService.ServiceBehaviour">
<federatedServiceHostConfiguration name="SecureWcfService.Service" />
<serviceMetadata httpGetEnabled="true" />
<serviceCredentials>
<serviceCertificate findValue="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="federatedServiceHostConfiguration" type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</behaviorExtensions>
</extensions>
<bindings>
<ws2007FederationHttpBinding>
<binding name="SecureWcfService.IService1_ws2007FederationHttpBinding">
<security mode="Message">
<message>
<issuerMetadata address="https://adfsserver/adfs/services/trust/mex" />
<claimTypeRequirements>
<add claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" isOptional="true" />
<add claimType="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" isOptional="true" />
</claimTypeRequirements>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<microsoft.identityModel>
<service>
<audienceUris>
<add value="https://wcfserver/SecureWcfService/Service1.svc" />
</audienceUris>
<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<trustedIssuers>
<add thumbprint="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" name="http://asfsserver/adfs/services/trust" />
<add thumbprint="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" name="http://adfsserver/adfs/services/trust" />
</trustedIssuers>
</issuerNameRegistry>
<certificateValidation certificateValidationMode="None" />
</service>
</microsoft.identityModel>
'未指定。在我看来,在继续使用WCF服务之前,您似乎需要遵循更多教程和/或阅读更多网页。如何使用WCF对于此网站来说是一个太宽泛的主题,但基本上,您需要在配置文件中定义一个绑定元素,以指定要使用联合服务在您的WCF服务中
仔细阅读MSDN上的页面。从链接页面:
在bindings部分中创建可用于与安全令牌服务通信的元素。有关创建绑定的详细信息,请参阅如何:在配置中指定服务绑定
您也可以阅读MSDN上的页面以获得进一步的背景阅读。我实现这一点的方法是根本不使用通过添加服务引用生成的配置,而是通过编程来完成。这就是我的工作:
//Helper to get SAML token from STS
public static SecurityToken GetSamlToken(string realm, string trustUrl, string userName, string password, string keyType, SecurityToken actAsToken = null)
{
var factory = new WSTrustChannelFactory(
//You will need to use WindowsWSTrustBinding here I think
new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
trustUrl
);
factory.TrustVersion = TrustVersion.WSTrust13;
//Here you would use Windows credentials instead of username/password
factory.Credentials.UserName.UserName = userName;
factory.Credentials.UserName.Password = password;
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
TokenType = TokenTypes.Saml2TokenProfile11,
KeyType = keyType, //I used KeyTypes.Bearer here
AppliesTo = new EndpointReference(realm)
};
if (actAsToken != null)
{
rst.ActAs = new SecurityTokenElement(actAsToken);
}
var token = factory.CreateChannel().Issue(rst);
return token;
}
var token = GetSamlToken(...);
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.Message);
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
var factory = new ChannelFactory<IService1>(binding, new EndpointAddress(serviceEndpoint));
ChannelFactoryOperations.ConfigureChannelFactory<IService1>(factory);
factory.Credentials.SupportInteractive = false;
factory.Credentials.UseIdentityConfiguration = true;
var channel = factory.CreateChannelWithIssuedToken<IService1>(token);
channel.CallSomeServiceMethod();
//帮助程序从STS获取SAML令牌
公共静态SecurityToken GetSamlToken(字符串域、字符串信任URL、字符串用户名、字符串密码、字符串密钥类型、SecurityToken actAsToken=null)
{
var工厂=新工厂(
//我想您需要在这里使用WindowsWSTrustBinding
新用户名WSTrustBinding(SecurityMode.TransportWithMessageCredential),
信任URL
);
factory.TrustVersion=TrustVersion.WSTrust13;
//在这里,您将使用Windows凭据而不是用户名/密码
factory.Credentials.UserName.UserName=用户名;
factory.Credentials.UserName.Password=密码;
var rst=新的RequestSecurityToken
{
RequestType=RequestTypes.Issue,
TokenType=TokenTypes.Saml2TokenProfile11,
KeyType=KeyType,//我在这里使用了KeyTypes.Bearer
AppliesTo=新端点引用(领域)
};
if(actAsToken!=null)
{
rst.ActAs=新的SecurityTokenElement(actAsToken);
}
var token=factory.CreateChannel().Issue(rst);
返回令牌;
}
var-token=GetSamlToken(…);
var binding=newWS2007FederationHttpBinding(WSFederationHttpSecurityMode.Message);
binding.Security.Message.EstablishSecurityContext=false;
binding.Security.Message.IssuedKeyType=SecurityKeyType.BearerKey;
var factory=newchannelfactory(绑定,新端点地址(serviceEndpoint));
ChannelFactoryOperations.ConfigureChannelFactory(工厂);
factory.Credentials.SupportInteractive=false;
factory.Credentials.UseIdentityConfiguration=true;
var通道=factory.CreateChannelWithIssuedToken(令牌);
channel.CallSomeServiceMethod();
谢谢@mclaaseen。我也通过代码获取令牌。上面提到的答案也有效。但我想通过使用配置隐式获取令牌