Reputation: 12419
Is it possible to set clientcredentials for an WCF in App.config?
I would like to avoid doing this:
Using svc As New MyServiceClient
svc.ClientCredentials.UserName.UserName = "login"
svc.ClientCredentials.UserName.Password = "pw"
...
End Using
Rather the login and password should be part of the configuration.
Upvotes: 12
Views: 29548
Reputation: 161
This is what I did to get the new auth to work
Expanding further on Mormegil's answer this is how to use the customBehavior implementation.
public class UserNameClientCredentialsElement : ClientCredentialsElement
{ // class renamed only to follow the configuration pattern
... // using Mormegil's implementation
}
After which you need to:
Using something like:
<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>
Upvotes: 12
Reputation: 8071
Expanding on Ladislav Mrnka’s answer, you might find this implementation useful:
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;
}
}
After which you need to register this custom implementation using something like
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="UserNameClientCredentials" type="MyNamespace.UserNameClientCredentials, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
...
Upvotes: 17
Reputation: 364249
You can try to inherit ClientCredentialsElement (handles default configuration section) and add support for UserName and Password. Than you can register this element in configuration file as behavior extension and use it instead of common configuration section.
Upvotes: 6
Reputation: 9469
As far as I know, that is not possible using the serviceModel configuration section due to the security hole it would create. But you could create regular appSettings for these values and use them in code:
svc.ClientCredentials.UserName.UserName = ConfigurationManager.AppSettings("...")
I would advise against this approach though, unless you encrypt the configuration file.
Upvotes: 9