2010-09-16 52 views
9

是否可以在App.config中爲WCF設置clientcredentials?在App.config中設置WCF ClientCredentials

我想避免這樣做:

Using svc As New MyServiceClient 
    svc.ClientCredentials.UserName.UserName = "login" 
    svc.ClientCredentials.UserName.Password = "pw" 

    ... 
End Using 

相反的登錄名和密碼應該是配置的一部分。

回答

8

據我所知,由於它會產生安全漏洞,所以使用serviceModel配置部分是不可能的。 但是你可以創建這些值常規的appSettings並在代碼中使用它們:

svc.ClientCredentials.UserName.UserName = ConfigurationManager.AppSettings("...") 

我會建議對這種做法雖然,除非你加密的配置文件。

+1

謝謝。但是將憑據存儲在AppSettings中仍然需要我以編程方式設置值。我確定這可能是一個安全問題,但我只是沒有看到其中的區別:無論如何,人們會將登錄/密碼存儲在某處 - 爲什麼不與其他WCF配置一起存儲? :) – 2010-09-16 14:03:54

+1

正如你所說,它與安全有關。向用戶提供以明文形式指定密碼的方法是一個明顯的安全漏洞。現在,如果開發人員決定用我提供的代碼繞過它,他會意識到他做錯了。他不能說「嘿,微軟,你的錯,你說它可以放入WCF配置。」 – 2010-09-16 16:40:47

4

您可以嘗試繼承ClientCredentialsElement(處理默認配置節)並添加對UserName和Password的支持。您可以將此元素作爲行爲擴展註冊到配置文件中,並使用它來代替通用配置部分。

12

擴展在拉吉斯拉夫Mrnka的答案,你可能會發現這個實現有用:

public class UserNameClientCredentials : ClientCredentialsElement 
{ 
    private ConfigurationPropertyCollection properties; 

    public override Type BehaviorType 
    { 
     get { return typeof (ClientCredentials); } 
    } 

    /// <summary> 
    /// Username (required) 
    /// </summary> 
    public string UserName 
    { 
     get { return (string) base["userName"]; } 
     set { base["userName"] = value; } 
    } 

    /// <summary> 
    /// Password (optional) 
    /// </summary> 
    public string Password 
    { 
     get { return (string) base["password"]; } 
     set { base["password"] = value; } 
    } 

    protected override ConfigurationPropertyCollection Properties 
    { 
     get 
     { 
      if (properties == null) 
      { 
       ConfigurationPropertyCollection baseProps = base.Properties; 
       baseProps.Add(new ConfigurationProperty(
            "userName", 
            typeof (String), 
            null, 
            null, 
            new StringValidator(1), 
            ConfigurationPropertyOptions.IsRequired)); 
       baseProps.Add(new ConfigurationProperty(
            "password", 
            typeof (String), 
            "")); 
       properties = baseProps; 
      } 
      return properties; 
     } 
    } 

    protected override object CreateBehavior() 
    { 
     var creds = (ClientCredentials) base.CreateBehavior(); 
     creds.UserName.UserName = UserName; 
     if (Password != null) creds.UserName.Password = Password; 
     ApplyConfiguration(creds); 
     return creds; 
    } 
} 

在這之後,你需要註冊使用的東西這個自定義實現像

<system.serviceModel> 
    <extensions> 
    <behaviorExtensions> 
     <add name="UserNameClientCredentials" type="MyNamespace.UserNameClientCredentials, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
    </behaviorExtensions> 
    </extensions> 
... 
+0

謝謝,它看起來像一個非常整潔的實現。我會在一天之內嘗試一下。 :) – 2011-09-13 06:26:18

8

這是我做得到新的驗證工作

Mormegil's answer上進一步擴展這是如何使用customBehavior實現。

public class UserNameClientCredentialsElement : ClientCredentialsElement 
{ // class renamed only to follow the configuration pattern 
    ... // using Mormegil's implementation 
} 

在這之後,你需要:

  1. 註冊behaviorExtension。
  2. 使用配置擴展名定義新的behaviorConfig。 (這是一個棘手的部分,關於如何做到這一點,報道很少。)
  3. 將配置應用到端點。

使用類似:

<system.serviceModel> 
    <client><!--(3)--> 
    <endpoint ...YourEndpointConfig... behaviorConfiguration="UserNamePasswordBehavior" /> 
    </client> 
    <behaviors><!--(2)--> 
    <endpointBehaviors> 
     <behavior name="UserNamePasswordBehavior"> 
     <userNameClientCredentials userName="skroob" password="12345" /> 
     <!--Visual Studio will give you warning squiggly on <userNameClientCredentials> 
      saying that "The element 'behavior' has invalid child element" 
      but will work at runtime.--> 
     </behavior> 
    </endpointBehaviors> 
    </behaviors> 
    <extensions><!--(1)--> 
    <behaviorExtensions> 
     <add name="userNameClientCredentials" type="MyNamespace.UserNameClientCredentialsElement, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
    </behaviorExtensions> 
    </extensions> 
    ... 
</system.serviceModel>