AspNet MVC - 对视图应用安全性?

时间:2009-10-21 10:30:55

标签: asp.net-mvc

我想在我的一个视图中添加集成的Windows安全性,这可能吗?

在网络表单上我只是在IIS中找到该文件并在那里添加文件安全功能,obv MVC是基于非文件的,这似乎不起作用。

该网站正在使用Forms Auth - 尝试将此功能用于MVC http://beensoft.blogspot.com/2008/06/mixing-forms-and-windows-authentication.html

由于

2 个答案:

答案 0 :(得分:5)

您可以在名为AuthorizeAttribute的Action方法上使用安全属性。

例如,

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

为了限制对链接等的访问,甚至将其隐藏在用户之外,我们实现了一个名为SecurityTrimmedActionLink的扩展方法,我们大多是从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;
}

答案 1 :(得分:1)

由于站点已在使用表单身份验证,因此您无法在控制器/操作上检查具有Authorize属性的角色或名称。因为那将使用当前的提供者(表单),而不是Windows。

快速而不那么优雅的解决方案是拥有类似下面的功能,并在返回视图之前检查它。

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

请注意,可能有更好的方法来执行此操作。我只是提供这个例子以防它可能有用。