views:

50

answers:

2

I want to do the same thing as in this link:

http://www.codeproject.com/KB/WCF/Custom_Authorization_WCF.aspx

But without using configuration files. Can anyone show me how?

Edit: I want to implement both AuthorizationPolicy and the CustomValidator.

+1  A: 

Are you referring about how to add the AuthorizationPolicy through code? Untested, but I believe something like this should work:

ServiceHost host = ...;
var col = new ReadOnlyCollection<IAuthorizationPolicy>(new IAuthorizationPolicy[] { new MyPolicy() });

ServiceAuthorizationBehavior sa = host.Description.Find<ServiceAuthorizationBehavior>();
if ( sa == null ) {
  sa = new ServiceAuthorizationBehavior();
  host.Description.Behaviors.Add(sa);
}
sa.ExternalAuthorizationPolicies = col;
tomasr
Thanks. Can you also show how I specify the CustomValidator with code?
jgauffin
Again, I haven't tried it, but ServiceCredentials is just another service behavior, so you should be able to just create an instance of ServiceCredentialsElement, set the UserNameAuthentication properties, then call CreateBehavior() on it and add to the ServiceHost.
tomasr
A: 

If you refer to the this topic (WCF Security: Getting the password of the user) by Rory Primrose, he achieves similar to what you're enquiring about with providing a custom validator, the important extension method being CreateSecurityTokenManager:

public class PasswordServiceCredentials : ServiceCredentials
{
    public PasswordServiceCredentials()
    {
    }

    private PasswordServiceCredentials(PasswordServiceCredentials clone)
        : base(clone)
    {
    }

    protected override ServiceCredentials CloneCore()
    {
        return new PasswordServiceCredentials(this);
    }

    public override SecurityTokenManager CreateSecurityTokenManager()
    {
        // Check if the current validation mode is for custom username password validation
        if (UserNameAuthentication.UserNamePasswordValidationMode == UserNamePasswordValidationMode.Custom)
        {
            return new PasswordSecurityTokenManager(this);
        }

        Trace.TraceWarning(Resources.CustomUserNamePasswordValidationNotEnabled);

        return base.CreateSecurityTokenManager();
    }
}

To use this custom service credential, you will need to specify the type attribute on the <ServiceCredentials>'s ConfigurationElement in your configuration, like:

<serviceCredentials type="your.assembly.namespace.PasswordServiceCredentials, 
     your.assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" >
</serviceCredentials>

Likewise, you could set this type attribute programatically, but I'm not familiar with how.

Rabid
You didn't read my question properly. Please do.
jgauffin
Sorry, but I've done all my customisation of WCF through configuration extensions (i.e. extension elements), but following from tomasr's lead, I believe he's suggesting you can set your CustomValidator by setting the following properties on the `UserNamePasswordServiceCredential` object accessed using `ServiceHostBase.Description.Behaviours.Find<ServiceCredentials>().UserNameAuthentication`: `UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom` and `UserNamePasswordValidator = new MyCustomValidator()`. Hope this helps!
Rabid
Well thats not explicitly what he's recommending, I believe he's suggesting that you could build your own service credentials configuration construct from scratch (`ServiceCredentialsElement`), set all the relevant properties (including the `UserNameAuthentication`), then substitute any `ServiceCredentials` already present within the described service host behaviours by constructing the behaviour via `ServiceCredentialsElement.CreateBehaviour()` - not straight forward though because it is declared as `protected internal abstract Object CreateBehavior()` on `BehaviorExtensionElement`
Rabid