每个端点的不同服务行为

时间:2012-09-06 07:06:09

标签: wcf claims-based-identity servicebehavior endpointbehavior

情况

我们正在某些WCF服务上实现不同类型的安全性。 ClientCertificate,UserName&密码和匿名。

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

一项服务的示例:

  • basicHttpBinding:Anonymous
  • basicHttpBinding:UserNameAndPassword
  • 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应用我们的授权策略。我们将使用端点行为,但我们无法在端点行为上指定我们的授权策略

1 个答案:

答案 0 :(得分:1)

授权是服务级别的责任。您无法通过端点更改它。

在高级别你应该:

  1. 定义端点绑定以使用您需要的(您做过的)不同的安全配置
  2. 创建自定义ClaimsAuthenticationManager以根据不同绑定所呈现的不同身份分配声明。
  3. 概念上,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>