2010-09-15 3 views
16

Я работаю над пользовательской аутентификацией и авторизацией WCF и нашел некоторые статьи о UserNamePasswordValidator и ServiceAuthorizationManager.Пользовательская аутентификация WCF с помощью System.ServiceModel.ServiceAuthenticationManager?

Я также нашел ключи об использовании пользовательского System.ServiceModel. ServiceAuthenticationManager (dead link), но msdn об этом не говорит много (http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceauthenticationmanager.aspx).

Итак, я: кто-нибудь знает больше об ServiceAuthenticationManager?

Как бы вы настраивали обычную проверку подлинности WCF?

+4

Это странно, но до сих пор там, кажется, много информации и образцов для ServiceAuthorizationManager, но вряд ли что-нибудь для ServiceAuthenticationManager – Cocowalla

ответ

35

Вы правы, документация на это совсем не помогает.

Способ, которым я использовал этот класс, заключается в следующем. Переопределение метода Аутентифицировать() по адресу:

  1. Потяните маркера аутентификации (например, имя пользователя/пароль) из входящего сообщения
  2. Аутентифицировать маркеры и использовать их для создания объекта IPrincipal. Это будет принцип, который используется при вызове операции обслуживания.
  3. Добавить объект IPrincipal в коллекцию message.Properties поэтому он может быть использован позже в конвейере обработки WCF

Вы не можете просто установить нить принципала в этот момент, как она изменяется позже с помощью WCF ,

Код в ServiceAuthenticationManager.Authenticate() методы будут выглядеть примерно так:

public override ReadOnlyCollection<IAuthorizationPolicy> Authenticate(ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri, ref Message message) 
{ 
    int tokenPosition = message.Headers.FindHeader("Token", "http://customnamespace.org"); 
    string token = message.Headers.GetHeader<string>(tokenPosition); 

    IPrincipal user = new CustomPrincipal(token); 

    message.Properties["Principal"] = user; 

    return authPolicy; 
} 

Затем добавить политику пользовательских авторизации,

  1. извлекает IPrincipal из сообщения (с помощью System.ServiceModel.EvaluationContext.Current.IncomingMessageProperties).
  2. Помещает IPrincipal в коллекцию EvaluationContext.Properties
  3. предъявляет претензии на основе метода IPrincipal.IsInRole

() Код в IAuthorizationPolicy() метод будет выглядеть

public bool Evaluate(EvaluationContext evaluationContext, ref object state) 
{ 
    IPrincipal user = OperationContext.Current.IncomingMessageProperties["Principal"] as IPrincipal; 
    evaluationContext.Properties["Principal"] = user; 
    evaluationContext.Properties["Identities"] = new List<IIdentity> { user.Identity }; 

    IList<Claim> roleClaims = this.GetRoleClaims(user); 

    evaluationContext.AddClaimSet(this, new DefaultClaimSet(this.Issuer, roleClaims)); 

    return true; 
} 

В конфигурации поведения службы вам необходимо установить mainPermissionMode = «Custom», чтобы WCF установил IPrincipal в качестве принципала в исполняемом потоке для фактического вызова службы.

<serviceAuthorization principalPermissionMode="Custom"... 
+1

Спасибо, что было очень полезно. Cheers :-) – fredlegrain

+0

Можно ли добавить идентификатор претензии в ClaimSet в ServiceAuthenticationManager.Authenticate() вместо того, чтобы помещать Принципала в свойства? –

+1

Возможно. Предполагаемый поток, я думаю, заключается в том, что AuthenticationManager проверяет учетные данные и делает принципал с претензиями, которые поступают непосредственно от поставщика удостоверений (требование идентификации было бы одним из них), AuthorizationPolicy преобразует претензии, а AuthorizationManager принимает решение о авторизации. Документация по этому поводу скудная, хотя так сложно сказать. Во всяком случае, теперь, когда доступен WIF, модель проще: o) –

Смежные вопросы