views:

161

answers:

1

I'm trying to set up a custom IAuthorisationPolicy that I can give to ServiceAuthorizationBehaviour to install my own IPrincipal implementation. I've followed the instructions here, and written a test that verifies that this works when self-hosting using a NetNamedPipes binding.

The problem is, when I try to use this hosted under IIS the Identities property is not being set in the evaluationContext that is passed to my IAuthorisationPolicy (whereas it is when self-hosting).

The following is an extract from my configuration file:

<customBinding>
        <binding name="AuthorisedBinaryHttpsBinding" receiveTimeout="00:03:00" sendTimeout="00:03:00">
          <security authenticationMode="UserNameOverTransport">
          </security>
          <binaryMessageEncoding>
          </binaryMessageEncoding>
          <httpsTransport />
        </binding>
      </customBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="CommonServiceBehaviour">
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
                                    membershipProviderName="AdminSqlMembershipProvider"/>
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

(Note that I'm configuring the ServiceAuthorisationBehavior through code, which is why it doesn't appear here)

Any idea why I'm not being passed the Identities property?

My IAuthorisationPolicy looks like this:

public class PrincipalInstallingAuthorisationPolicy : IAuthorizationPolicy
{
    public bool Evaluate(EvaluationContext evaluationContext, ref object state)
    {
        var identity = GetClientIdentity(evaluationContext);
        if (identity == null)
        {
            return false;
        }
            // var groups = get groups
            var principal = new GenericPrincipal(identity, groups);
            evaluationContext.Properties["Principal"] = principal;


        return true;
    }      

    private IIdentity GetClientIdentity(EvaluationContext evaluationContext)
    {
        object obj;
        if (!evaluationContext.Properties.TryGetValue("Identities", out obj))
        {
            return null;
        }

        IList<IIdentity> identities = obj as IList<IIdentity>;
        if (identities == null || identities.Count <= 0)
        {
            return null;
        }

        return identities[0];
    }

    ...
 }
+1  A: 

One thing to check - do you really set the serviceAuthorization's principalPermissionMode to "Custom" (as shown in the article you linked to)? That's crucial for your success.

<serviceAuthorization principalPermissionMode="Custom">

Also - could it be that you're calling your service as an anonymous user? In that case, you might get a "null" identity.

What's you client config like?? What bindings do you use, what security settings?

Marc

marc_s
Marc, I am definitely setting the mode to Custom - but I think you might have hit the nail on the head about the anonymous user - I was applying this behaviour to all my service, but forgotten that some of them are anonymous.
Samuel Jack