Различное поведение службы для конечной точки
Ситуация
Мы реализуем различные виды безопасности в некоторых сервисах WCF. ClientCertificate, UserName & Password и Anonymous.
У нас есть две конфигурации ServiceBehaviorConfiguration, одна для 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>
Как мы можем указать другое поведение службы на конечной точке WsHttpBinding? Или как мы можем применить нашу политику авторизации другим способом для wsHttpBinding, чем basicHttpBinding. Мы будем использовать поведение конечной точки, но не можем указать нашу политику авторизации для поведения конечной точки
1 ответ
Авторизация - это ответственность за уровень обслуживания. Вы не можете изменить его по конечной точке.
На высоком уровне вы должны:
- Определите привязки конечных точек для использования различных конфигураций безопасности, которые вам нужны (что вы сделали)
- Создайте пользовательский 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>