3

如何使我的 WCF 客户端使用 ACS 对我的内部托管 WCF 服务进行身份验证?问题围绕设置自定义领域(我不知道如何设置。)

我的 ACS 配置类似于ACS 示例,但是“领域”的定义如下所示。

Azure ACS 配置页面的摘录


领域定义


客户端代码

      EndpointAddress serviceEndpointAddress = new EndpointAddress( new Uri( "http://localhost:7000/Service/Default.aspx"),  
                                                                      EndpointIdentity.CreateDnsIdentity( GetServiceCertificateSubjectName() ),
                                                                      new AddressHeaderCollection() );

        ChannelFactory<IStringService> stringServiceFactory = new ChannelFactory<IStringService>(Bindings.CreateServiceBinding("https://agent7.accesscontrol.appfabriclabs.com/v2/wstrust/13/certificate"), serviceEndpointAddress );

        // Set the service credentials.
        stringServiceFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
        stringServiceFactory.Credentials.ServiceCertificate.DefaultCertificate = GetServiceCertificate();

        // Set the client credentials.
        stringServiceFactory.Credentials.ClientCertificate.Certificate = GetClientCertificateWithPrivateKey();

服务器端代码

 string acsCertificateEndpoint = String.Format( "https://{0}.{1}/v2/wstrust/13/certificate", AccessControlNamespace, AccessControlHostName );

        ServiceHost rpHost = new ServiceHost( typeof( StringService ) );

        rpHost.Credentials.ServiceCertificate.Certificate = GetServiceCertificateWithPrivateKey();

        rpHost.AddServiceEndpoint( typeof( IStringService ),
                                   Bindings.CreateServiceBinding( acsCertificateEndpoint ),
                                   "http://localhost:7000/Service/Default.aspx"
                                   );

        //
        // This must be called after all WCF settings are set on the service host so the
        // Windows Identity Foundation token handlers can pick up the relevant settings.
        //
        ServiceConfiguration serviceConfiguration = new ServiceConfiguration();
        serviceConfiguration.CertificateValidationMode = X509CertificateValidationMode.None;

        // Accept ACS signing certificate as Issuer.
        serviceConfiguration.IssuerNameRegistry = new X509IssuerNameRegistry( GetAcsSigningCertificate().SubjectName.Name );

        // Add the SAML 2.0 token handler.
        serviceConfiguration.SecurityTokenHandlers.AddOrReplace( new Saml2SecurityTokenHandler() );

        // Add the address of this service to the allowed audiences.
        serviceConfiguration.SecurityTokenHandlers.Configuration.AudienceRestriction.AllowedAudienceUris.Add( new Uri( "urn:federation:customer:222:agent:11") );

        FederatedServiceCredentials.ConfigureServiceHost( rpHost, serviceConfiguration );

        return rpHost;

...urn:federation:customer:222:agent:11信赖方 ID在哪里

...并且http://localhost:7000/Service/Default.aspx是我希望上述 WCF / WIF 客户端在进行 ACS 身份验证后绑定到的位置。

问题

如何编辑上面的代码,以便客户端和服务器都可以针对某个端口(localhost:700)以及 urn:federation:customer:222:agent:11 领域进行操作

我认为我的服务器代码正确;但是我如何AudienceRestriction在客户端上设置?

4

3 回答 3

4

您的服务器端代码看起来不错,但 Sixto 对标准通道工厂的看法是正确的。幸运的是,您可以使用 WSTrustChannelFactory 自己从 ACS 请求安全令牌。在您的示例上下文中,您的代码将如下所示:

//
// Get the token from ACS
//
WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(
    Bindings.CreateAcsCertificateBinding(),
    new EndpointAddress( acsCertificateEndpoint ) );
trustChannelFactory.Credentials.ClientCertificate.Certificate = GetClientCertificateWithPrivateKey();

RequestSecurityToken rst = new RequestSecurityToken()
{
    RequestType = RequestTypes.Issue,
    AppliesTo = new EndpointAddress( new Uri( "urn:federation:customer:222:agent:11" ) ),
    KeyType = KeyTypes.Symmetric
};

WSTrustChannel wsTrustChannel = (WSTrustChannel)trustChannelFactory.CreateChannel();
SecurityToken token = wsTrustChannel.Issue( rst );

//
// Call StringService, authenticating with the retrieved token
//
WS2007FederationHttpBinding binding = new WS2007FederationHttpBinding( WSFederationHttpSecurityMode.Message );
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.NegotiateServiceCredential = false;

ChannelFactory<IStringService> factory = new ChannelFactory<IStringService>(
    binding,
    new EndpointAddress(
            new Uri( ServiceAddress ),
            EndpointIdentity.CreateDnsIdentity(GetServiceCertificateSubjectName()) ) );
factory.ConfigureChannelFactory<IStringService>();
factory.Credentials.SupportInteractive = false;
factory.Credentials.ServiceCertificate.DefaultCertificate = GetServiceCertificate();

IStringService channel = factory.CreateChannelWithIssuedToken<IStringService>( token );
string reversedString = channel.Reverse( "string to reverse" );
于 2011-04-13T01:49:01.510 回答
1

有些答案可能迟到总比没有好。我一直无法找到任何有关以这种方式使用 WCF 的官方文档,但是在阅读 WS-Trust 论文和 MSDN 配置文档时,我提出了以下似乎可行的解决方案。

从服务消费客户端的配置中configuration/system.serviceModel/bindings/ws2007FederationHttpbinding/binding/security/message。它覆盖AppliesTo令牌请求消息的元素。

<tokenRequestParameters>
  <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
    <EndpointReference xmlns="http://www.w3.org/2005/08/addressing">
      <Address>urn:x-Organization:Testing</Address>
    </EndpointReference>
  </wsp:AppliesTo>
</tokenRequestParameters>

在服务的配置中添加相同的片段,将导致服务引用实用程序将其包含在trust:SecondaryParameters服务客户端的元素中。它必须移动到父tokenRequestParameters元素中才能正常工作。

于 2013-06-19T18:43:25.257 回答
0

实际上并没有尝试过这篇 MSDN 文章中引用的方法,但从阅读中听起来标准通道工厂没有正确的钩子来做你想做的事。WSTrustChannelFactory 是为 WIF 和 SAML 构建的,但我对 ACS 不够熟悉,无法确定它是否适用。这个由六部分组成的系列中的这篇文章可能也值得仔细阅读。

于 2011-04-12T20:32:55.477 回答