8

情况

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

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

一项服务的示例:

  • basicHttpBinding : 匿名
  • basicHttpBinding : 用户名和密码
  • 基本HttpBinding : 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。我们将使用端点行为,但我们不能在端点行为上指定我们的授权策略

4

1 回答 1

2

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

在高层次上,您应该:

  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>
于 2012-09-06T18:50:13.743 回答