Вы правы, документация по этому вопросу совершенно не помогает.
То, как я использовал этот класс, заключается в следующем.Переопределите метод Authenticate () следующим образом:
- Извлеките токены аутентификации (например, имя пользователя / пароль) из входящего сообщения
- Аутентифицируйте токены и используйте их для создания объекта IPrincipal.Это будет принципал, который используется во время вызова операции службы.
- Добавьте объект 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;
}
Затем вы добавляете пользовательскую политику авторизации, которая
- Извлекает IPrincipal из сообщения (используя коллекцию System.ServiceModel.EvaluationContext.Current.IncomingMessageProperties).
- ВыдвигаетIPrincipal в коллекцию EvaluationContext.Properties
- Делает заявки на основе метода 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"...