【问题标题】:Set WCF ClientCredentials in App.config在 App.config 中设置 WCF ClientCredentials
【发布时间】:2011-04-13 02:56:47
【问题描述】:

是否可以在 App.config 中为 WCF 设置客户端凭据?

我想避免这样做:

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

  ...
End Using

登录名和密码应该是配置的一部分。

【问题讨论】:

    标签: c# .net vb.net wcf configuration


    【解决方案1】:

    这就是我为使新的身份验证工作所做的工作

    进一步扩展 Mormegil's answer 这是如何使用 customBehavior 实现。

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

    之后您需要:

    1. 注册行为扩展。
    2. 使用配置扩展定义一个新的行为配置。 (这是棘手的部分,关于如何做到这一点的报道很少。)
    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>
    

    【讨论】:

      【解决方案2】:

      扩展 Ladislav 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>
      ...
      

      【讨论】:

      • 谢谢,它看起来是一个非常简洁的实现。有一天我会试试的。 :)
      【解决方案3】:

      您可以尝试继承ClientCredentialsElement(处理默认配置部分)并添加对用户名和密码的支持。您可以在配置文件中将此元素注册为行为扩展,并使用它来代替通用配置部分。

      【讨论】:

        【解决方案4】:

        据我所知,使用 serviceModel 配置部分是不可能的,因为它会产生安全漏洞。 但是您可以为这些值创建常规 appSettings 并在代码中使用它们:

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

        我建议不要使用这种方法,除非您加密配置文件。

        【讨论】:

        • 谢谢。但是将凭据存储在 AppSettings 中仍然需要我以编程方式设置值。我确定这可能是一个安全问题,但我只是看不出区别:人们无论如何都会将登录名/密码存储在某个地方 - 为什么不与 WCF 配置的其余部分一起存储呢? :)
        • 如你所说,与安全有关。为用户提供一种以明文形式指定密码的方法是一个明显的安全漏洞。现在,如果开发人员决定用我提供的代码绕过它,他会意识到自己的错误行为。他将无法说“嘿微软,你的错,你说可以把它放在 WCF 配置中。”
        猜你喜欢
        • 1970-01-01
        • 2010-09-30
        • 2011-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-01
        • 2023-03-26
        相关资源
        最近更新 更多