2014年8月19日 星期二

在authentication mode="Forms"下使用 membership defaultProvider="ADMembershipProvider", 搭配Fluent Security的測試及如何使用AD群組來做權限控管

參考這篇,
Fluent Security - 在MVC集中管理頁面權限的套件

真的不錯用, 但受到Form登入無法直接使用 AD的群組當Roles的影響.

所以只能用上

configue.ForAllControllers().Ignore();

configue.For<HomeController>().DenyAnonymousAccess();

configue.For<HomeController>().DenyAuthenticatedAccess();

而一直找不到使用角色的辦法..

configue.For<HomeController>(hc => hc.Contact()).RequireAnyRole("Everyone");

只好回頭用自訂 action filter的辦法來處理 AD的Group.

1.加入參考
C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.DirectoryServices.AccountManagement.dll

2. Using System.DirectoryServices.AccountManagement;

3.使用者登入時取回AD Group資料塞入Session, 給自訂Action Filter及View使用.
 [HttpPost]
    public ActionResult Login(LoginModel model, string returnUrl)
    {
        if (!this.ModelState.IsValid)
        {
            return this.View(model);
        }

        if (Membership.ValidateUser(model.UserName, model.Password))
        {
            //取回AD Group資料塞入Session
            var context = new PrincipalContext(ContextType.Domain, "Adimmune");
            var userPrincipal = UserPrincipal.FindByIdentity(context,
                                                 IdentityType.SamAccountName,
                                                 model.UserName);
            var UGS = userPrincipal.GetAuthorizationGroups();
            string uGroup = "";
            foreach (var ug in UGS)
                uGroup = uGroup + ug.Name + ";";
            SessionHelper.UserGroup = uGroup;

            FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
            if (this.Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
            {
                return this.Redirect(returnUrl);
            }

            return this.RedirectToAction("Index", "Home");
        }

        this.ModelState.AddModelError(string.Empty, "您提供的Windows帳號或密碼並不正確,如有疑問請與資訊人員聯絡.");

        return this.View(model);
    }

//!!切記要在LogOff時清空SessionHelper.UserGroup,否則會影響權限控管
 public ActionResult LogOff()
    {
        SessionHelper.UserGroup = "";
        SessionHelper.RealName = "";
        FormsAuthentication.SignOut();

        return this.RedirectToAction("Index", "Home");
    }

4.自訂Action Filter.
 public class AuthorizeADAttribute : AuthorizeAttribute
    {
        public string Groups { get; set; }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
                /* Return true immediately if the authorization is not
                locked down to any particular AD group */
                if (String.IsNullOrEmpty(Groups))
                    return true;

                // Get the AD groups
                var groups = Groups.Split(',').ToList<string>();

                // Verify that the user is in the given AD group (if any)
                foreach (var group in groups)
                            if (SessionHelper.UserGroup.Contains(group+";"))
                            return true;                
            return false;
        }

5. Control使用範例

 [AuthorizeAD(Groups = "IT")]
 public class empsController : Controller
    {
..................................
}

6 View使用範例
if (Session["UserGroup"].ToString().Contains("webAdmin01;"))
                    {
                        <ul class="nav pull-right">
                            <li class="dropdown">
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown">後台管理<b class="caret"></b></a>
                                <ul class="dropdown-menu">
                                    <li><a href="@Url.Action("Index", "emps")"><i class="icon-off"></i>員工</a></li>
                                    <li><a href="@Url.Action("Index", "deps")"><i class="icon-off"></i>部門</a></li>
                                    <li><a href="@Url.Action("Index", "exms")"><i class="icon-off"></i>評核類別</a></li>
                                    <li><a href="@Url.Action("Index", "ots")"><i class="icon-off"></i>評核時間</a></li>
                                    <li><a href="@Url.Action("Index", "ts")"><i class="icon-off"></i>評核紀錄</a></li>
                                    <li><a href="@Url.Action("Index", "actlogs")"><i class="icon-off"></i>Logs</a></li>
                                </ul>
                            </li>
                        </ul>
                    }

沒有留言:

張貼留言