2009-02-09 5 views
4

У меня есть служба WCF, которая использует пользовательский ServiceAuthorizationManager. Пользовательский менеджер авторизации уже настроен для проверки подлинности Windows и форм.WCF UserName Authentication: могу ли я получить имя пользователя в пользовательском ServiceAuthorizationManager?

Однако, если я подключаюсь к клиенту, который установлен в 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?


Update: Так я добавил обычай 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> 

Если я поставил точку останова во всех 3 из этих классов, 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) 

Перед любым из них бежать. Hmmm ...

ответ

5

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

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 это имя нашего пароля валидатор)

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

+0

Спасибо! Для тех, кому это может понадобиться позже, вот как добавить настраиваемую авторизациюPolicy: http://msdn.microsoft.com/en-us/library/ms729794.aspx – CodingWithSpike

+0

В чем может быть проблема, если «Идентичность» является нулевой ? У меня тоже есть «обычай» mainPermissionMode и AuthorizationPolicy, как у вас в вашем примере – Juri

+0

@Juri - тогда это звучит как анонимно ... за этим трудно ответить. –