【问题标题】:Different Service behaviors per endpoint每个端点的不同服务行为
【发布时间】:2012-08-30 22:53:19
【问题描述】:

情况

我们正在对某些 WCF 服务实施不同类型的安全性。 ClientCertificate、用户名和密码以及匿名。

我们有 2 个 ServiceBehaviorConfiguration,一个用于 httpBinding,一个用于 wsHttpBinding。 (我们有针对基于声明的安全性的自定义授权策略) 作为要求,我们需要为每个服务提供不同的端点。 3 个端点使用 httpBinding,1 个端点使用 wsHttpBinding。

一项服务的示例:

  • basicHttpBinding:匿名
  • basicHttpBinding:用户名和密码
  • basicHttpBinding : BasicSsl
  • wsHttpBinding : BasicSsl

注意:我们正在开发 .NET 3.5

问题

第 1 部分:我们不能两次指定同一个服务,一次使用 http 服务配置,一次使用 wsHttp 服务配置。

第 2 部分: 我们无法在端点上指定服务行为。 (抛出异常,未找到端点行为...服务行为无法设置为端点行为)

配置

第 1 部分:

<services>
  <service name="Namespace.MyService" behaviorConfiguration="securityBehavior">
   <endpoint address="http://server:94/MyService.svc/Anonymous" contract="Namespace.IMyService" binding="basicHttpBinding" bindingConfiguration="Anonymous">
    </endpoint> 
    <endpoint address="http://server:94/MyService.svc/UserNameAndPassword" contract="Namespace.IMyService" binding="basicHttpBinding" bindingConfiguration="UserNameAndPassword">
    </endpoint>
    <endpoint address="https://server/MyService.svc/BasicSsl" contract="Namespace.IMyService" binding="basicHttpBinding" bindingConfiguration="BasicSecured">
    </endpoint>
  </service>
  <service name="Namespace.MyService" behaviorConfiguration="wsHttpCertificateBehavior">
    <endpoint address="https://server/MyService.svc/ClientCert" contract="Namespace.IMyService" binding="wsHttpBinding" bindingConfiguration="ClientCert"/>
  </service>
</services>

服务行为配置:

<serviceBehaviors>
<behavior name="securityBehavior">
  <serviceAuthorization serviceAuthorizationManagerType="Namespace.AdamAuthorizationManager,Assembly">
    <authorizationPolicies>
      <add policyType="Namespace.AdamAuthorizationManager,Assembly" />
    </authorizationPolicies>
  </serviceAuthorization>
</behavior>
<behavior name="wsHttpCertificateBehavior">
  <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
  <serviceAuthorization serviceAuthorizationManagerType="Namespace.AdamAuthorizationManager,Assembly">
    <authorizationPolicies>
      <add policyType="Namespace.AdamAuthorizationManager,Assembly" />
    </authorizationPolicies>
  </serviceAuthorization>
  <serviceCredentials>
    <clientCertificate>
      <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck"/>
    </clientCertificate>
    <serviceCertificate findValue="CN=CertSubject"/>
  </serviceCredentials>
</behavior>

我们如何在 WsHttpBinding 端点上指定不同的服务行为? 或者我们如何以不同的方式将我们的授权策略应用于 wsHttpBinding 和 basicHttpBinding。我们将使用端点行为,但我们无法在端点行为上指定我们的授权策略

【问题讨论】:

    标签: wcf claims-based-identity servicebehavior endpointbehavior


    【解决方案1】:

    授权是服务级别的责任。你不能通过端点来改变它。

    您应该:

    1. 定义端点绑定以使用您需要的不同安全配置(您已经这样做了)
    2. 创建自定义ClaimsAuthenticationManager,以根据不同绑定将呈现的不同身份分配声明。

    从概念上讲,ClaimsAuthenticationManager 充当“服务中的 STS”,根据不同的凭据添加声明。从那里您可以在您的服务中进行基于声明的授权。

    我不知道有任何可配置的授权管理器确实需要你想要的,所以你必须自己编写(如果你证明我错了,请发布你发现的内容)。

    实现 ClaimsAuthenticationManager 需要Windows Identity Framework。下面是我使用的 .NET 4.0 实现的摘要(这在 4.5 中可能更容易)。我很抱歉代码没有编译并且不完整,但我没有时间为公开帖子清理所有内容。不过,这应该会为您指明正确的方向。

    Microsoft.IdentityModel.Claims.ClaimsAuthenticationManager 继承并实现 Authenticate()。它应该看起来像这样:

    namespace MyWCF.ClaimsInjection
    {
        public class ClaimsAuthenticationManager : Microsoft.IdentityModel.Claims.ClaimsAuthenticationManager
        {
            public override IClaimsPrincipal Authenticate(string resourceName, IClaimsPrincipal incomingPrincipal)
            {
                if (incomingPrincipal == null)
                {
                    throw new ArgumentNullException("incomingPrincipal", "ClaimInjectionClaimsAuthenticationManager requires a principal.");
                }
    
                IClaimsPrincipal resultPrincipal = base.Authenticate(resourceName, incomingPrincipal);
                foreach (IIdentity identity in resultPrincipal.Identities)
                {
                    if (identity is ClaimsIdentity)
                    {
                        // Add claims based on client cert here…
                        Claim identityClaim = ((ClaimsIdentity)identity).Claims.First(c => c.ClaimType == ClaimTypes.Thumbprint);
                        ((ClaimsIdentity)identity).Claims.Add(new Claim("MyType", "Myvalue"));
                    }
                    else if (identity is WindowsClaimsIdentity)
                    {
                        // Add claims based on window group or account here…
                    }
    
                    // continue checking different identity types...
                }
                return resultPrincipal;
            }
        }
    }
    

    现在只需安装自定义管理器(仅包括有趣的部分):

    <configuration>
      <configSections>
        <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </configSections>
    
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="serviceBehavior">
              <federatedServiceHostConfiguration />
            </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>
      </system.serviceModel>
    
      <microsoft.identityModel>
        <service>
          <claimsAuthenticationManager type="MyWCF.ClaimsAuthenticationManager, MyWCF"/>
        </service>
      </microsoft.identityModel>
    </configuration>
    

    【讨论】:

    • ClaimsAuthenticationManager 没有问题,我们有自己的实现。这部分工作,使用 httpBinding。但是我们很难将 wsHttpBinding 和 BasicHttpBinding 结合起来。明天我会更深入地研究它,并随时通知您。
    • 在这种情况下,只需将您的 ClaimsAuthenticationManager 应用一次作为服务行为,并确保它可以在同一个 Authenticate() 实现中处理 wsHttp 和 BasicHttp 呈现的身份......你应该完成了。跨度>
    猜你喜欢
    • 2021-01-14
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多