Пользовательская аутентификация WCF с System.ServiceModel.ServiceAuthenticationManager? - PullRequest
16 голосов
/ 15 сентября 2010

Я работаю над пользовательской аутентификацией и авторизацией WCF и нашел несколько статей о UserNamePasswordValidator и ServiceAuthorizationManager .

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

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

В общем, как бы вы настроили пользовательскую аутентификацию WCF?

1 Ответ

36 голосов
/ 01 октября 2010

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

То, как я использовал этот класс, заключается в следующем.Переопределите метод Authenticate () следующим образом:

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

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

<serviceAuthorization principalPermissionMode="Custom"...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...