2

I would like to add integrated windows security to one of my views, is this possible?

On web-forms I would just find the file in IIS and add the file security features there, obv MVC being non-file based this doesnt seem to work.

The site is using Forms Auth - Trying to make this work for MVC http://beensoft.blogspot.com/2008/06/mixing-forms-and-windows-authentication.html

Thanks

1
  • I think it would be better if you edit the question and say that the site is already using forms authentication. Commented Oct 21, 2009 at 11:09

2 Answers 2

5

You can use security attributes on the Action methods called the AuthorizeAttribute.

For example,

[Authorize(Roles = "Domain Users")]
public ActionResult Create(FormCollection collection)

To then restrict access to links or such, or even hide them from users, we implemented an extension method called SecurityTrimmedActionLink which we mostly adapted/borrowed from http://www.inq.me/post/ASPNet-MVC-Extension-method-to-create-a-Security-Aware-HtmlActionLink.aspx.

public static string SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, object routeValues)
{
    if (IsAccessibleToUser(action, htmlHelper.ViewContext.Controller))
    {
        return htmlHelper.ActionLink(linkText, action, routeValues);
    }

    return string.Empty;
}

public static string SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action)
{
    return SecurityTrimmedActionLink(htmlHelper, linkText, action, null);
}

private static bool IsAccessibleToUser(string action, ControllerBase controller)
{
    ArrayList controllerAttributes = new ArrayList(controller.GetType().GetCustomAttributes(typeof(AuthorizeAttribute), true));
    ArrayList actionAttributes = new ArrayList();
    MethodInfo[] methods = controller.GetType().GetMethods();
    foreach (MethodInfo method in methods)
    {
        object[] attributes = method.GetCustomAttributes(typeof(ActionNameAttribute), true);
        if ((attributes.Length == 0 && method.Name == action) || (attributes.Length > 0 && ((ActionNameAttribute)attributes[0]).Name == action))
        {
            actionAttributes.AddRange(method.GetCustomAttributes(typeof(AuthorizeAttribute), true));
        }
    }
    if (controllerAttributes.Count == 0 && actionAttributes.Count == 0)
        return true;

    IPrincipal principal = HttpContext.Current.User;
    string roles = "";
    string users = "";
    if (controllerAttributes.Count > 0)
    {
        AuthorizeAttribute attribute = controllerAttributes[0] as AuthorizeAttribute;
        roles += attribute.Roles;
        users += attribute.Users;
    }
    if (actionAttributes.Count > 0)
    {
        AuthorizeAttribute attribute = actionAttributes[0] as AuthorizeAttribute;
        roles += attribute.Roles;
        users += attribute.Users;
    }

    if (string.IsNullOrEmpty(roles) && string.IsNullOrEmpty(users) && principal.Identity.IsAuthenticated)
        return true;

    string[] roleArray = roles.Split(',');
    string[] usersArray = users.Split(',');
    foreach (string role in roleArray)
    {
        if (role == "*" || principal.IsInRole(role))
            return true;
    }
    foreach (string user in usersArray)
    {
        if (user == "*" || (principal.Identity.Name.Equals(user, StringComparison.InvariantCultureIgnoreCase)))
            return true;
    }
    return false;
}
Sign up to request clarification or add additional context in comments.

7 Comments

Yea this is fine, but in our case we dont have set roles. What I am trying to do is add Integrated Windows Security to a couple of Views (The rest of the site is form auth) - msdn.microsoft.com/en-us/library/ms972958.aspx
Use can set Authorize(Users = "Pete User") as well... look up other examples of the use of AuthorizeAttribute. =)
You can even leave it at [Authorize] to let the method know you simply want an authorized user.
Thats all great, but its not helping in mixing the auth modes?
Might have a look at this, as well: blog.wekeroad.com/blog/…
|
1

Since the site is already using forms authentication, you won't be able to check the roles or names with the Authorize attribute on your controllers/actions. Because that will use the current provider (forms), instead of the Windows.

A quick and not-so-elegant solution would be having a function like the one below and checking against it before returning the view.

bool IsWindowsAuthenticated() {
    //the following classes are under System.Security.Principal
    WindowsIdentity identity = WindowsIdentity.GetCurrent();
    WindowsPrincipal principal = new WindowsPrincipal(identity);
    return principal.Identity.IsAuthenticated;
}

Note that there might be a better way to do this. I'm just providing that example in case it might be useful.

2 Comments

Nice. I forgot I only used the HttpContext user principal in the method I posted. =)
@J. Steen, I was going to explain that in the comments but then I thought an answer would be better.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.