2009-08-18 24 views
7

Quiero asegurar un punto final de un servicio WCF, no sé si puede asegurar algunos puntos finales y otros no. A continuación tengo el servicio WCF eliminado (alojado por mí mismo). El mismo WCF sirve también el archivo de política de CA. Si aseguro este servicio WCF o algunos puntos finales de ut, la parte de la Política de CA no debe pedirme una contraseña de usuario. El archivo de política debe estar accesible todo el tiempo. ¿Eso también es posible?Protección del punto final del servicio WCF con autenticación personalizada

Encontré muchos blogs/publicaciones personalizadas de WCF. Hay muchas maneras de hacer seguridad. Todo lo que quiero es que pueda asegurar algunos puntos finales con nombre de usuario/contraseña, pero las credenciales no deben ser visibles con herramientas como Fiddler. Los datos, sin embargo, pueden ser visibles en este caso.

Implementé ya un Customvalidator pero el archivo app.config también es importent para definir las cosas. Y no soy muy bueno en eso.

namespace WindowsFormsApplication11 
{ 
    public partial class Form1 : Form 
    { 
     public ServiceHost _host = null; 

     public Form1() 
     { 
      InitializeComponent(); 
     }  

     private void button1_Click(object sender, EventArgs e) 
     { 
      // Create a ServiceHost for the CalculatorService type and 
      // provide the base address. 
      _host = new ServiceHost(typeof(WmsStatService)); 
      _host.AddServiceEndpoint(typeof(IPolicyProvider), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior()); 

      _host.Open(); 
     } 
    } 

    // Define a service contract. 
    [ServiceContract(Namespace = "http://WindowsFormsApplication11")] 
    public interface IWmsStat 
    { 
     [OperationContract] 
     string getConnectedViewers(string channelName); 
     [OperationContract] 
     string sayHello(string name); 
    } 

    [ServiceContract] 
    public interface IPolicyProvider 
    { 
     [OperationContract, WebGet(UriTemplate = "/ClientAccessPolicy.xml")] 
     Stream ProvidePolicy(); 
    } 
    //[DataContract] 
    public class Ads 
    { 
     // [DataMember] 
     public string AdFileName { get; set; } 
     //[DataMember] 
     public string AdDestenationUrl { get; set; } 
     public string ConnectedUserIP { get; set; } 
    } 
    // 
    public class CustomValidator : UserNamePasswordValidator 
    { 
     public override void Validate(string userName, string password) 
     { 
      if(null == userName || null == password) 
      { 
        throw new ArgumentNullException(); 
      } 
      if(userName == "Oguz" && password == "2009") 
      { 
       return; 
      } 
      FaultCode fc = new FaultCode("ValidationFailed"); 
      FaultReason fr = new FaultReason("Good reason"); 
      throw new FaultException(fr,fc); 
     } 
    } 
    // 

    public class WmsStatService : IWmsStat, IPolicyProvider 
    { 
     public string sayHello(string name) 
     { 
      return "hello there " + name + " nice to meet you!"; 
     } 

     public Stream ProvidePolicy() 
     { 
      WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml"; 
      return new MemoryStream(File.ReadAllBytes("ClientAccessPolicy.xml"), false); 
     } 

     public string getConnectedViewers(string channelname) 
     { 
      // do stuff 
      return null; 
     } 
    } 
} 

The app.config. Este archivo de configuración no funciona. Quería poner la autenticación personalizada para un punto final. No tengo ni idea.

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
    <services> 
     <service name="WindowsFormsApplication11.WmsStatService" behaviorConfiguration="mex"> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://192.168.0.199:87" /> 
      </baseAddresses> 
     </host>   
     <endpoint address="http://192.168.0.199:87/Test" binding="basicHttpBinding" bindingConfiguration="" contract="WindowsFormsApplication11.IWmsStat" behaviorConfiguration="MyServiceBehavior" /> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services> 

    <!--<bindings> 
     <wsHttpBinding>  
     <binding name="wshttp"> 
      <security mode="Message"> 
      <message clientCredentialType="UserName" /> 
      </security> 
     </binding> 
     </wsHttpBinding> 
    </bindings>--> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior name="mex"> 
      <serviceMetadata httpGetEnabled="true" httpGetUrl=""/> 
     </behavior> 
     <behavior name="MyServiceBehavior"> 
      <serviceCredentials> 
      <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WindowsFormsApplication11.CustomValidator, CustomValidator" /> 
      </serviceCredentials> 
     </behavior> 
     </serviceBehaviors>  
    </behaviors> 
    </system.serviceModel> 
</configuration> 

Respuesta

17

quiero conseguir algún punto final de un servicio WCF , no sé si se puede conseguir algún punto final y otros no.

Claro - sólo tiene que crear dos configuraciones de unión separados, y utilizar una de esas puntos finales que están asegurados, el otro sobre los demás:

<bindings> 
    <basicHttpBinding> 
    <binding name="secured"> 
     <security mode="Message"> 
     <message ...... /> 
     </security> 
    </binding> 
    <binding name="unsecured"> 
     <security mode="None" /> 
    </binding> 
    </basicHttpBinding> 
</bindings> 
<services> 
    <service name="WindowsFormsApplication11.WmsStatService" behaviorConfiguration="mex"> 
    <host> 
     <baseAddresses> 
     <add baseAddress="http://192.168.0.199:87" /> 
     </baseAddresses> 
    </host>   

    <endpoint address="/Secured/Test" 
       binding="basicHttpBinding" bindingConfiguration="secured" 
       contract="WindowsFormsApplication11.IWmsStat" 
       behaviorConfiguration="MyServiceBehavior" /> 

    <endpoint address="/Unsecured/Test" 
       binding="basicHttpBinding" bindingConfiguration="unsecured" 
       contract="WindowsFormsApplication11.IWmsStat" 
       behaviorConfiguration="MyServiceBehavior" /> 

    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
    </service> 
</services> 

Marc

PS: No estoy seguro si ese es solo un problema con las publicaciones que ya no están actualizadas, ¿ha notado que tiene dos configuraciones de comportamiento separadas:

<behaviors> 
    <serviceBehaviors> 
     <behavior name="mex"> 
     <serviceMetadata httpGetEnabled="true" httpGetUrl=""/> 
     </behavior> 
     <behavior name="MyServiceBehavior"> 
     <serviceCredentials> 
      <userNameAuthentication 
       userNamePasswordValidationMode="Custom" 
       customUserNamePasswordValidatorType="WindowsFormsApplication11.CustomValidator, CustomValidator" /> 
     </serviceCredentials> 
     </behavior> 
    </serviceBehaviors>  
</behaviors> 

y su servicio solo hace referencia al comportamiento "mex"? Eso significa que su servicio está usando efectivamente el comportamiento <serviceMetadata>, pero NO el <serviceCredentials> uno!

necesita fusionar estos en uno y luego hacer referencia sólo eso:

<behaviors> 
    <serviceBehaviors> 
     <behavior name="Default"> 
     <serviceMetadata httpGetEnabled="true" httpGetUrl=""/> 
     <serviceCredentials> 
      <userNameAuthentication 
       userNamePasswordValidationMode="Custom" 
       customUserNamePasswordValidatorType="WindowsFormsApplication11.CustomValidator, CustomValidator" /> 
     </serviceCredentials> 
     </behavior> 
    </serviceBehaviors>  
</behaviors> 
<services> 
    <service name="...." behaviorConfiguration="Default" 

Marc

+0

Maldición estoy haciendo esto ahora :( No se pudo cargar el archivo o ensamblado 'CustomValidator' o uno de sus dependencias El sistema no puede encontrar el archivo especificado – Shift

+0

Ese error proviene de esta configuración aquí: es eso de montaje "CustomValidator" disponibles al ejecutar su servicio ?? –

+0

me cambió eso a WindowsFormsAppiication11. se trata de un auto acogió WCF servicio en Windows Forms. Después de que cambié eso a lo que dije que el error se ha ido, pero otro problema :( The ChannelDispatcher en 'http://192.168.0.199:87/Test' con contrato (s) '"IWmsStat"' no puede abrir su IChannelListener – Shift

2

Si desea proteger todo el mensaje, el modo de seguridad de transporte es un camino a seguir. Si solo desea cifrar/firmar sus encabezados, el modo de seguridad de mensajes lo permite, pero deberá usar wsHttpBinding. También puede considerar usar Digest para proteger las credenciales.

En cuanto a su ejemplo, creo que su parte comentado debería tener este aspecto:

<bindings> 
    <basicHttpBinding> 
      <binding name="secure"> 
     <security mode="Transport"> 
     <transport clientCredentialType="Basic" /> 
     </security> 
    </binding> 
    </basicHttpBinding> 
</bindings> 

También tendrá que actualizar su declaración de punto final:

<endpoint 
    address="https://192.168.0.199:87/Test" 
    binding="basicHttpBinding" bindingConfiguration="secure" 
    contract="WindowsFormsApplication11.IWmsStat" /> 

No se le permitirá para usar HTTP simple con el modo de seguridad de transporte.

+0

Con esa configuración que estoy recibiendo el siguiente error. no hay ningún comportamiento punto final denominado 'MyServiceBehavior' – Shift

+0

no quiero usar https por lo que he seleccionado el modo de seguridad Mensaje – Shift

+0

mover behaviorConfiguration = "CalculatorServiceBehavior"> a la etiqueta de servicio –

Cuestiones relacionadas