每个端点的不同服务行为

Pre*_*hts 7 wcf claims-based-identity servicebehavior endpointbehavior

情况

我们正在某些WCF服务上实现不同类型的安全性.ClientCertificate,UserName&Password和Anonymous.

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

一项服务的示例:

  • basicHttpBinding:匿名
  • 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>
Run Code Online (Sandbox Code Playgroud)

服务行为配置:

<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>
Run Code Online (Sandbox Code Playgroud)

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

Ern*_*ieL 2

授权是服务级别的责任。您可以\xe2\x80\x99t 按端点更改它。

\n\n

在高层次上,你应该:

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

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

\n\n

我\xe2\x80\x99m不知道任何可配置的授权管理器会满足你的需要,所以你\xe2\x80\x99必须编写你自己的(如果你证明我错了,请发布你发现的内容)。

\n\n

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

\n\n

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

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

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

\n\n
<configuration>\n  <configSections>\n    <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />\n  </configSections>\n\n  <system.serviceModel>\n    <behaviors>\n      <serviceBehaviors>\n        <behavior name="serviceBehavior">\n          <federatedServiceHostConfiguration />\n        </behavior>\n      </serviceBehaviors>\n    </behaviors>\n\n    <extensions>\n      <behaviorExtensions>\n        <add name="federatedServiceHostConfiguration" type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />\n      </behaviorExtensions>\n    </extensions>\n  </system.serviceModel>\n\n  <microsoft.identityModel>\n    <service>\n      <claimsAuthenticationManager type="MyWCF.ClaimsAuthenticationManager, MyWCF"/>\n    </service>\n  </microsoft.identityModel>\n</configuration>\n
Run Code Online (Sandbox Code Playgroud)\n