在 App.config 中设置 WCF ClientCredentials
Posted
技术标签:
【中文标题】在 App.config 中设置 WCF ClientCredentials【英文标题】:Set WCF ClientCredentials in App.config 【发布时间】: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
登录名和密码应该是配置的一部分。
【问题讨论】:
【参考方案1】:这就是我为使新的身份验证工作所做的工作
进一步扩展 Mormegil's answer 这是如何使用 customBehavior 实现。
public class UserNameClientCredentialsElement : ClientCredentialsElement
// class renamed only to follow the configuration pattern
... // using Mormegil's implementation
之后您需要:
-
注册行为扩展。
使用配置扩展定义一个新的行为配置。 (这是棘手的部分,关于如何做到这一点的报道很少。)
将配置应用到端点。
使用类似的东西:
<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 配置中。”以上是关于在 App.config 中设置 WCF ClientCredentials的主要内容,如果未能解决你的问题,请参考以下文章
C#的app.Config文件中设置,可以选择执行环境(左配置,有程序),app.Config中的appSettings首字母必须小写,符合源码要求