Ответ 1
Вы правы, документация на этом вообще не нужна.
Способ, которым я использовал этот класс, выглядит следующим образом. Переопределите метод 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;
}
В конфигурации поведения службы вам необходимо установить mainPermissionMode = "Custom", чтобы WCF установил IPrincipal в качестве принципала в исполнительном потоке для фактического вызова службы.
<serviceAuthorization principalPermissionMode="Custom"...