2017-05-20 3 views
1

ich eine einfache wcf mit benutzerdefinierter Authentifizierung und AutorisierungWCF Authentifizierung und Autorisierung funktioniert nicht

<system.serviceModel> 
    <client /> 
    <bindings> 
     <basicHttpBinding> 
     <binding name="secureHttpBinding"> 
      <security mode="TransportWithMessageCredential"> 
      <message clientCredentialType="UserName" /> 
      </security> 
     </binding> 
     </basicHttpBinding> 
    </bindings> 
    <services> 
     <service name="WcfService1.Service1" behaviorConfiguration="customBehaviour"> 
     <endpoint address="" 
        binding="basicHttpBinding" 
        bindingConfiguration="secureHttpBinding" 
        contract="WcfService1.IService1"/> 

     <endpoint address="mex" 
        binding="mexHttpsBinding" 
        contract="IMetadataExchange" /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceMetadata httpGetEnabled="true"/> 
      <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     <behavior name="customBehaviour"> 

      <serviceMetadata httpGetEnabled="true"/> 

      <serviceDebug includeExceptionDetailInFaults="true"/> 
      <serviceCredentials> 
      <userNameAuthentication userNamePasswordValidationMode="Custom" 
       customUserNamePasswordValidatorType="WcfService1.UserAuthentication,WcfService1"/> 
      </serviceCredentials> 

      <serviceAuthorization principalPermissionMode="Custom"> 
      <authorizationPolicies> 
       <add policyType="WcfService1.AuthorizationPolicy, WcfService1" /> 
      </authorizationPolicies> 
      </serviceAuthorization> 


     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <protocolMapping> 
     <add binding="basicHttpsBinding" scheme="https" /> 
    </protocolMapping>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 

Mit dieser Implementierung erstellen:

public class AuthorizationPolicy: IAuthorizationPolicy 
    { 
     string id = Guid.NewGuid().ToString(); 

     public string Id 
     { 
      get { return this.id; } 
     } 

     public ClaimSet Issuer 
     { 
      get { return ClaimSet.System; } 
     } 

     public bool Evaluate(EvaluationContext context, ref object state) 
     { 
      object obj; 
      if (!context.Properties.TryGetValue("Identities", out obj)) 
       return true; 

      IList<IIdentity> identities = obj as IList<IIdentity>; 
      if (obj == null || identities.Count <= 0) 
       return true; 

      context.Properties["Principal"] = new CustomPrincipal(identities[0]); 
      return true; 
     } 
    } 
    class CustomPrincipal : IPrincipal 
    { 
     IIdentity identity; 
     public CustomPrincipal(IIdentity identity) 
     { 
      this.identity = identity; 
     } 

     public IIdentity Identity 
     { 
      get { return this.identity; } 
     } 

     public bool IsInRole(string role) 
     { 

      return true; 
     } 
    } 

Und

public class UserAuthentication : UserNamePasswordValidator 
    { 
     public override void Validate(string userName, string password) 
     { 
      try 
      { 
       if (userName == "test" && password == "test123") 
       { 
        Console.WriteLine("Authentic User"); 
       } 
      } 
      catch (Exception ex) 
      { 
       throw new FaultException("Unknown Username or Incorrect Password"); 
      } 
     } 
    } 

Ich lade meine Service unter ssl in meinem lokalen iis und ruf meinen Service in meinem Klienten so an:

static void Main(string[] args) 
     { 
      ServiceReference1.Service1Client serviceProxy = new ServiceReference1.Service1Client(); 
      serviceProxy.ClientCredentials.UserName.UserName = "test"; 
      serviceProxy.ClientCredentials.UserName.Password = "test123"; 

      PatientData objData = new PatientData(); 
      objData.Name = "test"; 
      objData.Gender = "Male"; 
      objData.Email = "[email protected]"; 
      objData.Age = 20; 
      string message = serviceProxy.GetData(5); 
      //Console.WriteLine(serviceProxy.UpdatePatientData(objData)); 


      Console.WriteLine(message); 
      Console.ReadLine(); 
     } 

Mit dieser config:

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
      <binding name="BasicHttpBinding_IService1"> 
       <security mode="TransportWithMessageCredential" /> 
      </binding> 
     </basicHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="https://union-pc58.union.com/Service1.svc" 
      binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" 
      contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" /> 
    </client> 
</system.serviceModel> 

Aber wie Sie können mein Benutzername ist test und Passwort ist test123, aber wenn ich mein Passwort ändern in der Client-Seite funktioniert alles einwandfrei und die zurückgegebenen Daten zu sehen ist wieder? !!! warum?

Antwort

1

Vielleicht eine Ausnahme aus, wenn der Benutzername und das Passwort nicht in Ihrer Validate-Methode entsprechen:

public override void Validate(string userName, string password) 
{ 
    try 
    { 
     if (userName == "test" && password == "test123") 
     { 
      Console.WriteLine("Authentic User"); 
     } else { 
      throw new Exception(); 
     } 
    } 
    catch (Exception ex) 
    { 
     throw new FaultException("Unknown Username or Incorrect Password"); 
    } 
} 

oder mehr vereinfacht:

public override void Validate(string userName, string password) 
{ 
    if (userName != "test" && password != "test123") 
    { 
     throw new FaultException("Unknown Username or Incorrect Password");  
    } 
} 

Es ist auch gut für die NULL-Werte zu überprüfen:

if (null == userName || null == password) 
    { 
     throw new ArgumentNullException(); 
    } 
Verwandte Themen