Jakob Gade
Jakob Gade

Reputation: 12419

Set WCF ClientCredentials in App.config

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

Answers (4)

Patrick Paquet
Patrick Paquet

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:

  1. Register the behaviorExtension.
  2. Define a new behaviorConfig using the config extension. (which was the tricky part, coverage is scarce on how to do this.)
  3. Apply the config to an endpoint.

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

Mormegil
Mormegil

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

Ladislav Mrnka
Ladislav Mrnka

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

Johann Blais
Johann Blais

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

Related Questions