Различное поведение службы для каждой конечной точки

Ситуация

Мы реализуем различные виды безопасности для некоторых служб WCF. ClientCertificate, UserName & Password и Anonymous.

У нас есть 2 ServiceBehaviorConfigurations, один для httpBinding и один для wsHttpBinding. (У нас есть настраиваемые политики авторизации для безопасности на основе утверждений) В качестве требования нам нужны разные конечные точки для каждой службы. 3 конечные точки с httpBinding и 1 с wsHttpBinding.

Пример для одной услуги:

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

Конфигурация поведения службы:

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

How can we specify a different service behaviour on the WsHttpBinding endpoint? Or how can we apply our authorization policy in a different way for wsHttpBinding then basicHttpBinding. We would use endpoint behavior but we can't specify our authorization policy on an endpoint behavior


person Preben Huybrechts    schedule 06.09.2012    source источник


Ответы (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>
person ErnieL    schedule 06.09.2012
comment
У нас нет проблем с ClaimsAuthenticationManager, у нас есть собственная реализация. Эта часть работает с использованием httpBinding. Но нам сложно объединить wsHttpBinding и BasicHttpBinding. Завтра я займусь этим подробнее и буду держать вас в курсе. - person Preben Huybrechts; 06.09.2012
comment
В этом случае просто примените свой ClaimsAuthenticationManager один раз в качестве поведения службы и убедитесь, что он может обрабатывать как wsHttp, так и BasicHttp представленные идентификаторы в одной реализации Authenticate () ... и все готово. - person ErnieL; 07.09.2012