Аутентификация имени пользователя WCF: Могу ли я получить имя пользователя в пользовательском ServiceAuthorizationManager? - PullRequest
4 голосов
/ 09 февраля 2009

У меня есть служба WCF, использующая пользовательский ServiceAuthorizationManager. Пользовательский менеджер аутентификации уже настроен для обработки аутентификации Windows и Forms.

Однако, если я соединяюсь с клиентом, для которого установлен UserName auth, я не могу нигде найти имя пользователя.

Код клиента выглядит следующим образом:

this.ClientCredentials.UserName.UserName = "user";
this.ClientCredentials.UserName.Password = "pass";
this.Open();
this.MyMethod(); // my actual contract method
this.Close();

Затем на сервере у меня есть свой собственный менеджер аутентификации:

public sealed class AppAuthorizationManager : ServiceAuthorizationManager
{
    public override bool CheckAccess(OperationContext operationContext, ref Message message)
    {
        // would like to check user/pwd here...
    }
}

Возможно ли это?

  • Thread.CurrentPrincipal не установлен,
  • operationContext.ServiceSecurityContext.PrimaryIdentity не установлен.
  • operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets пусто.

Предполагается, что пользователь / pwd где-нибудь доступен? Или мне тоже нужно добавить кастом UsernamePasswordValidator?


Обновление: Поэтому я добавил пользовательский UserNamePasswordValidator и IAuthorizationPolicy. Мой обновленный конфиг WCF выглядит так:

<behavior name="Server2ServerBehavior">
  <serviceMetadata httpGetEnabled="true" />
  <serviceDebug includeExceptionDetailInFaults="true" />
  <serviceAuthorization principalPermissionMode="Custom" serviceAuthorizationManagerType="MyApp.AuthManager, MyApp">
    <authorizationPolicies>
      <add policyType="MyApp.TokenAuthorizationPolicy, MyApp" />
    </authorizationPolicies>
  </serviceAuthorization>
  <serviceCredentials>
    <userNameAuthentication customUserNamePasswordValidatorType="MyApp.PFUserNameValidator, MyApp" />
  </serviceCredentials>
</behavior>

Если я установлю точку останова во всех этих трех классах, WCF выдаст исключение:

LogonUser failed for the 'username' user. Ensure that the user has a valid Windows account.
   at System.IdentityModel.Selectors.WindowsUserNameSecurityTokenAuthenticator.ValidateUserNamePasswordCore(String userName, String password)

До того, как какой-либо из них будет запущен. Ммм ...

1 Ответ

6 голосов
/ 09 февраля 2009

Обычно это обрабатывается в UsernamePasswordValidator - единственном месте, где у вас будет доступ к паролю. Однако, это не то место, где вы устанавливаете принципал - это будет в IAuthorizationPolicy методе Evaluate, который может выглядеть примерно так:

bool IAuthorizationPolicy.Evaluate(
    EvaluationContext evaluationContext, ref object state)
{           
    IList<IIdentity> idents;
    object identsObject;
    if (evaluationContext.Properties.TryGetValue(
        "Identities", out identsObject) && (idents =
        identsObject as IList<IIdentity>) != null)
    {
        foreach (IIdentity ident in idents)
        {
            if (ident.IsAuthenticated &&
                ident.AuthenticationType == TrustedAuthType)
            {                           
                evaluationContext.Properties["Principal"]
                    = //TODO our principal
                return true;
            }
        }
    }
    if (!evaluationContext.Properties.ContainsKey("Principal"))
    {
        evaluationContext.Properties["Principal"] = //TODO anon
    }                
    return false;
}

(где TrustedAuthType - имя нашего средства проверки пароля)

С этим будет установлен основной участник потока, и мы сможем идентифицировать себя (и использовать безопасность на основе ролей и т. Д.)

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