如何在MVC应用程序中使用Windows身份验证使用自定义角色

时间:2017-06-27 14:26:58

标签: windows-authentication asp.net-mvc-5

我正在使用Windows身份验证(WA)开发内部MVC应用程序。然而,使用WA验证用户是直截了当的;关于用户角色,我有以下要求:

  1. 我们将使用忽略AD角色的自定义角色。例如,用户 可能在AD中具有“经理”角色,但他的应用角色设置为 “主管”。用户通过身份验证后,系统将获取 用户角色并相应地设置CurrentPrincipal。

  2. 对于上述内容,我计划有3个表,包括用户角色 UserRole 角色表具有自定义角色 用户表由公司用户组成。 UserRole 表将定义 用户与其角色之间的映射。我用这种方法看到的问题 是预先填充所有3个表。用户表必须包含所有列表 公司员工,并为新员工/非员工员工维护。 UserRole 在登录之前,应该为每个用户及其角色设置表格。

  3. 在应用程序中,用户被分配到不同的任务(例如John是 监督车辆)我们需要维护用户活动日志。假设 以上两点是有效的,可以在用户中使用 ID字段 为此目的的表?

  4. 稍后我们可能会部署该应用程序 在公共领域。在这种情况下,我们如何使用现有的 用于此目的的用户/角色基础架构。

  5. 提前致谢。

1 个答案:

答案 0 :(得分:0)

我的朋友,你和我一模一样!我设法通过自定义授权属性执行此操作。以下是我在这个过程中偶然发现的几点。

我没有创建自己的用户表。您可以,但您可以根据您域中的用户数量为用户查询AD,并使用Guid进行搜索将其链接到您的角色/活动表。如果您确实创建了一个镜像AD的用户表,会为用户使用Guid 。这样,如果登录/名称/其他任何更改,Guid保持不变。

自定义授权属性:

namespace YourSite.Attributes
{   
    [AttributeUsage(AttributeTargets.Method)]
    public class AuthRoleAttribute : ActionFilterAttribute
    {
        public string RoleName { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!ViewIsAuthorizedActivity(RoleName)) // create a bool function to see if your user is in this role... check your db or whatever
            {
                string requestMethod = filterContext.HttpContext.Request.HttpMethod;

                if (requestMethod == "GET")// I chose two different means of forbidding a user... this just hides the part of the page based on the @if(ViewBag.Authorization = "FORBIDDEN") where you render a partial, else show the view 
                {
                    filterContext.Controller.ViewBag.Authorization = "FORBIDDEN";
                }
                else if (requestMethod == "POST") // This prevents over posting by redirecting them completely away from that controller... also prevents them from posting if they have the page loaded and you remove permission
                {                                 // Hiding a part of the page doesn't matter for the POST if the page is already loaded
                    filterContext.Result = new RedirectToRouteResult(
                        new RouteValueDictionary
                            {
                                { "controller", "Home" },
                                { "action", "Forbidden" },
                                { "area", ""}
                            });
                }

                base.OnActionExecuting(filterContext);
            }
        }           
    }
}

如何在视图中处理GET:

@if (ViewBag.Authorization == "FORBIDDEN")
{
    ViewBag.Title = "Forbidden!";
    @Html.Partial("~/Views/Forbidden.cshtml");
}
else
<!-- User is not forbidden and have the view here -->

请注意,对于POST,用户将从控制器重定向到Forbidden控制器。

控制器上的属性:

[AuthRole(RoleName = "Admin")]
public ActionResult YourController()

我还对用户进行了扩展,因此如果他们没有获得许可,可能会隐藏在视图中:

public static bool IsAuthorized(this IPrincipal user, string roleName)
    {
        return Attributes.AuthActivityAttribute.ViewIsAuthorizedByRole(roleName); // function determining if the user is in that role, therefore show what you want to show in the view or don't show it if false
    }

由以下人员召集:

@if (User.IsAuthorized("Admin"))
{
<!-- show something, a link, etc. -->
}

希望这比你有更好的开端。如果您有疑问,请告诉我。