views:

457

answers:

2

I am using ASP.NET MVC 1.1 with Windows authentication. I trying to only authorize members of a group and myself. I am not a member of the group and would not need to be a member of this group. I am getting windows login/password prompt every time I access the URL of the web app. The HomeController has

[HandleError]
[Authorize(Roles=@"MyDomain\\company.security.group.name")]  
[Authorize(Users=@"MyDoamin\\MyName")]
[OutputCache(Duration=86400,VaryByParam="PageIndex")]
public class HomeController : Controller

How do I enable such authorization? The web app is running under a site on IIS6. The site has directory security to accept anonymous. The web app/virtual directory has anonymous disabled and Windows Integrated security enabled. The web.config has

A: 

You can subtype AuthorizeAttribute to look at Users and Roles. off the top of my head (untested):

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    // This method must be thread-safe since it is called by the thread-safe OnCacheAuthorization() method.
    protected virtual bool AuthorizeCore(HttpContextBase httpContext) {
        base.AuthorizeCore(httpContext);

        if ((!string.IsNullOrEmpty(Users) && (_usersSplit.Length == 0))
           (!string.IsNullOrEmpty(Roles) && (_rolesSplit.Length == 0)))
        {
            // wish base._usersSplit were protected instead of private...
            InitializeSplits();                
        }

        IPrincipal user = httpContext.User;
        if (!user.Identity.IsAuthenticated) {
            return false;
        }

        var userRequired = _usersSplit.Length > 0);
        var userValid = userRequired
            && _usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase);

        var roleRequired = _rolesSplit.Length > 0);
        var roleValid = (roleRequired) 
            && _roleSplit.Any(user.IsInRole);

        var userOrRoleRequired = userRequired || roleRequired;

        return (!userOrRoleRequired) || userValid || roleValid;
    }

    private string[] _rolesSplit = new string[0];
    private string[] _usersSplit = new string[0];

    private void InitializeSplits()
    {
        lock(this)
        {
            if ((_rolesSplit.Length == 0) || (_usersSplit.Length == 0))
            {
                _rolesSplit = SplitString(Roles);
                _usersSplit = SplitString(Users);
            }
        }
    }
}
Craig Stuntz
There is something missing in the posted the custom attribute code. I managed to debug and compiled it. It didn't work. Here is the attribute declaration. [MyAuthorize(Roles=@"MyDomain\\company.security.group.name",Users=@"MyDoamin\\MyName"))]
Can you elaborate on "didn't work," please?
Craig Stuntz
I know this is an old post, but what you seem to have missed is that `@` eliminates the need to escape your backslashes. When you do both, you create a string literal that contains two backslashes, instead of the single slash that you need.
David Lively
+1  A: 

As you are prefixing your domain/user and domain/group strings with the '@' character you do not need to double escape the backslash. You could try replacing these lines with either:

[Authorize(Roles="MyDomain\\company.security.group.name")]  
[Authorize(Users="MyDoamin\\MyName")]

or

[Authorize(Roles=@"MyDomain\company.security.group.name")]  
[Authorize(Users=@"MyDoamin\MyName")]

A bit of further reading has also revealed that the Authorize filter will perform a 'users' and 'roles' check. If the user doesn't meet both requirements then they will be refused access.
To get the behaviour you want you will need to write a custom authorisation filter as suggested in a previous answer.

Andy Rose