2009-08-18 5 views
7

Desidero proteggere alcuni endpoint di un servizio WCF, non so se è possibile proteggere alcuni endpoint e altri no. Di seguito ho il servizio WCF stripped (self hosted). Lo stesso WCF serve anche il file di politica CA. Se proteggi questo servizio WCF o alcuni endpoint di ut la parte di CA Policy non deve chiedermi una password di nome utente. Il file della politica deve essere sempre accessibile. È anche possibile?Protezione dell'endpoint del servizio WCF con autenticazione personalizzata

Ho trovato molti blog/post personalizzati WCF. Ci sono molti modi per fare sicurezza. Tutto quello che voglio è che posso proteggere alcuni endpoint con nome utente/password ma le credenziali non devono essere visibili con strumenti come Fiddler. I dati tuttavia possono essere visibili in questo caso.

Ho implementato già un Customvalidator ma il file app.config è anche importante per definire le cose. E non sono molto bravo in questo.

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; 
     } 
    } 
} 

L'app.config. Questo file di configurazione non funziona. Volevo mettere l'autenticazione personalizzata per un endpoint. Non ho 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> 

risposta

17

voglio garantire alcuni endpoint di un servizio WCF , non so se si può garantire alcuni endpoint e altri no.

Certo - basta creare due configurazioni vincolanti separati, e utilizzare uno su quei punti finali che sono protetti, l'altro sugli altri:

<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: non è sicuro se questo è solo un problema con i tuoi messaggi non sono più aggiornati - hai notato che hai due configurazioni di comportamento separate:

<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> 

e il tuo servizio fa riferimento solo al comportamento "mex"? Ciò significa che il tuo servizio utilizza effettivamente il comportamento <serviceMetadata> - ma NON quello <serviceCredentials>!

è necessario unire questi in uno e quindi fare riferimento proprio questo:

<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

Accidenti sto ottenendo questo ora :( Impossibile caricare il file o l'assembly 'CustomValidator' o una delle sue dipendenze Il sistema non riesce a trovare il file specificato – Shift

+0

Tale errore viene da questa config qui: è questo montaggio "CustomValidator" disponibile quando si esegue il servizio ?? –

+0

ho cambiato che a WindowsFormsAppiication11. Questo è un self ospitato WCF servizio su Windows Form. Dopo averlo cambiato in quello che ho detto che l'errore è andato, ma un altro problema :( Il ChannelDispatcher a 'http://192.168.0.199:87/Test' con contratto (i) '"IWmsStat"' non è in grado di aprire il proprio IChannelListener – Shift

2

Se si desidera proteggere l'intero messaggio, la modalità di protezione del trasporto è un modo per andare. Se vuoi che solo le tue intestazioni siano crittografate/firmate, la modalità di sicurezza dei messaggi lo consente, ma dovrai usare wsHttpBinding. Potresti anche considerare l'utilizzo di Digest per proteggere le credenziali.

Per quanto riguarda il tuo esempio, penso che la tua parte commentato dovrebbe assomigliare a questa:

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

Avrete anche di aggiornare il tuo dichiarazione finale:

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

Non sarà consentito utilizzare il semplice HTTP con la modalità di sicurezza del trasporto.

+0

Con tale configurazione sto ottenendo il seguente errore. Non v'è nessun comportamento endpoint denominata 'MyServiceBehavior' – Shift

+0

non voglio usare https così ho selezionato la modalità di protezione del messaggio – Shift

+0

spostare behaviorConfiguration = "CalculatorServiceBehavior"> per il numero di servizio –