views:

265

answers:

2

I'm implementing role based security using Microsoft's membership and role provider.

The theoretical problem I'm having is that you implement a specific role on a method such as:

[PrincipalPermissionAttribute(SecurityAction.Demand, Role="Supervisor")]
private void someMethod() {}

What if at some point down the road, I don't want Supervisors to access someMethod() anymore?

Wouldn't I have to change the source code to make that change? Am I missing something?

It seems there has to be some way to abstract the relationship between the supervisors role and the method so I can create a way in the application to change this coupling of role permission to method.

Any insight or direction would be appreciated. Thank you.

+1  A: 

If you use the declarative approach, then yes - if you suddenly don't want members of the Supervisor to be able to call your method, you need to change your source code for that.

You can, however, also do all of this in code, programmatically:

private void someMethod() 
{
    WindowsPrincipal currentUser = (Thread.CurrentPrincipal as WindowsPrincipal);
    if (currentUser != null)
    {
        if (currentUser.IsInRole("Supervisor"))
        {
            // do something here
        }
    }

}

You can always get the current Windows principal your Winforms app is running under, and then you can call the IsInRole method to check whether or not a given user is in a given role. Of course, you can also make all of this configurable, e.g. read the required role from a config file, and if you want to allow everyone in, you just simply change the role to be Users or something

marc_s
A: 

PrincipalPermissionAttribute does not tend to be used in many applications I've worked on for the reason you've touched upon; the attribute applies a policy which can only be altered by a code change.

The alternative is to use the PrincipalPermission class directly. All security attributes resolve to similarly named classes and method calls at run time. In the case of your attribute, the following code is executed:

PrincipalPermission permission = new PrincipalPermission(null, "Supervisor");
permission.Demand(); // Throws SecurityException if user is not in the role.

If you use the permission classes directly, you gain more control over how your permissions are formed. You could have a database which you query to get a list of roles and perform a demand for them like this:

private void someMethod()
{
    IEnumerable<string> roles = GetRolesForMethod("someMethod");

    PrincipalPermission permission = null;

    foreach(string role in roles)
    {
        if(permission == null)
        {
            permission = new PrincipalPermission(null, role);
        }
        else
        {
            permission = permission.Union(
                new PrincipalPermission(null, role);
                );
        }
    }

    if(permission != null)
    {
        permission.Demand();
    }
}
Programming Hero