Midimatt
Midimatt

Reputation: 1114

WCF CustomRoleProvider and Principle Permissions

EDIT: I think that the issue may be related to the issue below as I'm also using SSL PrincipalPermission.Demand() failing once WCF Service was moved to SSL

I'm working on a secure set of web services, I've implemented a CustomRoleProvider and CustomMembershipProvider in order to authenticate users.

This works great, however I would like to restrict access to the majority of service calls if the user is not authenticated.

i planned on using the following to accomplish this

[PrincipalPermission(SecurityAction.Demand, Authenticated=true)]

However, this doesn't seem to detect when a user is authenticated and always throws a security exception. I'm not really sure what I've done wrong.

public class CustomMembershipProvider : MembershipProvider
{
    public string UserType;

    public override bool ValidateUser(string username, string password)
    {
           //Custom logic to work out if user exists and password is correct

           //If the user exists and password matches we will get a populated user
           //object containing their username and usertype

            if (user == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }

Within my authentication service call i check if the membership provider returns true and sets a forms authentication cookie.

        if (Membership.ValidateUser(username, password))
        {
            FormsAuthentication.SetAuthCookie(username, false);
        }

I've set up service Authorization in my web config as follows:

    <behavior name="SecureAuthServiceBehavior">
      <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="CustomRoleProvider"/>
      .... 
     </behaviour>

Any help would be greatly appreciated, Thanks

EDIT:

I've done some further investigation into the issue and discovered that the Principal is being set correctly. i have the following Service method, within it I get the Principal and check if the user is in the correct role, effectively doing what the tag at the start is doing.

[PrincipalPermission(SecurityAction.Demand,Role="A" )]
public bool DoWork()
{
    IPrincipal p = HttpContext.Current.User;
    if (p.IsInRole("A"))
    {
        return true;
    }
    else
    {
        return false;
     }
}

This method currently throws a SecurityException every time however if I comment out the principal permission at the start then the method works and returns true.

Upvotes: 1

Views: 1971

Answers (1)

Adam
Adam

Reputation: 533

PrincipalPermission checks the Thread.CurrentPrincipal, not the HttpContext.Current.User, that's why with the principalpermission attribute commented out your DoWork() returns true, but with that line present it returns false (because Thread.CurrentPrincipal isn't set to anything).

In the constructor of my service class I set Thread.CurrentPrincipal = HttpContext.Current.User and now they match up correctly. The principalpermission attribute then blocks/allows as you would expect it to.

Upvotes: 1

Related Questions