C# 在App.config中设置WCF客户端凭据
是否可以在App.config中为WCF设置clientcredentials 我希望避免这样做:C# 在App.config中设置WCF客户端凭据,c#,.net,vb.net,wcf,configuration,C#,.net,Vb.net,Wcf,Configuration,是否可以在App.config中为WCF设置clientcredentials 我希望避免这样做: Using svc As New MyServiceClient svc.ClientCredentials.UserName.UserName = "login" svc.ClientCredentials.UserName.Password = "pw" ... End Using 相反,登录名和密码应该是配置的一部分。据我所知,使用serviceModel配置部分是不可能的,
Using svc As New MyServiceClient
svc.ClientCredentials.UserName.UserName = "login"
svc.ClientCredentials.UserName.Password = "pw"
...
End Using
相反,登录名和密码应该是配置的一部分。据我所知,使用serviceModel配置部分是不可能的,因为它会造成安全漏洞。 但您可以为这些值创建常规appSettings,并在代码中使用它们:
svc.ClientCredentials.UserName.UserName = ConfigurationManager.AppSettings("...")
不过,我建议不要使用这种方法,除非您加密配置文件。您可以尝试继承(处理默认配置部分)并添加对用户名和密码的支持。然后,您可以在配置文件中将此元素注册为行为扩展名,并使用它来代替公共配置部分。扩展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;
}
}
公共类UserNameClientCredentials:ClientCredentialsElement
{
私有配置属性集合属性;
公共重写类型BehaviorType
{
获取{return typeof(ClientCredentials);}
}
///
///用户名(必填)
///
公共字符串用户名
{
获取{return(string)base[“userName”];}
设置{base[“userName”]=value;}
}
///
///密码(可选)
///
公共字符串密码
{
获取{return(string)base[“password”];}
设置{base[“password”]=value;}
}
受保护的覆盖配置属性集合属性
{
得到
{
如果(属性==null)
{
ConfigurationPropertyCollection baseProps=base.Properties;
baseProps.Add(新配置属性(
“用户名”,
类型(字符串),
无效的
无效的
新的StringValidator(1),
ConfigurationPropertyOptions.IsRequired));
baseProps.Add(新配置属性(
“密码”,
类型(字符串),
""));
属性=基本道具;
}
归还财产;
}
}
受保护的重写对象CreateBehavior()
{
var creds=(ClientCredentials)base.CreateBehavior();
creds.UserName.UserName=用户名;
如果(Password!=null)creds.UserName.Password=Password;
应用程序配置(creds);
回信;
}
}
之后,您需要使用以下内容注册此自定义实现
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="UserNameClientCredentials" type="MyNamespace.UserNameClientCredentials, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
...
...
这就是我为了让新的身份验证生效所做的
在此基础上进一步扩展的是如何使用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>
...
谢谢。但是在AppSettings中存储凭据仍然需要我以编程方式设置这些值。我确信这可能是一个安全问题,但我看不出有什么区别:人们无论如何都会将登录/pw存储在某个地方——为什么不将其与WCF配置的其余部分一起存储呢??)正如你所说,这与安全有关。为用户提供以明文指定密码的方法是一个明显的安全漏洞。现在,如果开发人员决定使用我提供的代码对其进行旁路,他将意识到自己的错误。他不会说“嘿,微软,是你的错,你说把它放在WCF配置中没问题。”谢谢,这看起来是一个非常简洁的实现。总有一天我会试试的