如何配置 WCF 以将 URN 格式的自定义领域与 Azure ACS 结合使用?

发布于 2024-10-31 09:15:27 字数 3552 浏览 5 评论 0原文

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

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

摘自 Azure ACS 配置页面


realmDefinition


客户端代码

      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();

< strong>服务器端代码

 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 是我希望在进行 ACS 身份验证后将上述 WCF / WIF 客户端绑定到的位置。

问题

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

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

How do I make my WCF client authenticate using the ACS to my internally hosted WCF service? The issue revolves around setting a custom Realm (which I can't figure out how to set.)

My ACS is configured similar to the ACS Samples however the "Realm" is defined as shown below.

Excerpt from Azure ACS Configuration page


realm definition


Client Side Code

      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();

Server Side Code

 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;

... where urn:federation:customer:222:agent:11 is the Relying party ID

... and http://localhost:7000/Service/Default.aspx is the location I want the above WCF / WIF client to bind to once the ACS authentication is made.

Question

How do I edit the code above so that the client and server will both operate against a certain port (localhost:700) and also with a realm of urn:federation:customer:222:agent:11

I think I have the server code correct; however how do I set AudienceRestriction on the client?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

看透却不说透 2024-11-07 09:15:27

您的服务器端代码看起来不错,但 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" );

Your server side code looks fine, but Sixto is right about standard channel factories. Luckily, you can request a security token from ACS yourself using a WSTrustChannelFactory. In the context of your sample, your code would look like this:

//
// 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" );
心碎的声音 2024-11-07 09:15:27

有些答案迟到总比不到好。我一直无法找到任何有关以这种方式使用 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 元素中才能正常工作。

Some answers may be better late than never. I've been unable to find any official documentation on using WCF in this fashion, however in reading the WS-Trust papers and the MSDN documentation on configuration, I have come up with the following solution which appears to work.

From the service consuming client's config at configuration/system.serviceModel/bindings/ws2007FederationHttpbinding/binding/security/message. It overrides the AppliesTo element of the token request message.

<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>

Adding this same snippet in the configuration of the service, will cause the Service Reference utility to include this within the trust:SecondaryParameters element of the service client. It must be moved into the parent tokenRequestParameters element to work properly.

爱本泡沫多脆弱 2024-11-07 09:15:27

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

Haven't actually tried the approach referenced in this MSDN article but from reading it sounds like the standard channel factory doesn't have the right hooks to do what you want. The WSTrustChannelFactory is built for WIF & SAML but I'm not familiar enough with ACS to determine if it is applicable. This article in this six-part series will probably be worthwhile perusing too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文