ASP.NET MVC表单身份验证+授权属性+简单角色

我试图将简单的身份验证和授权添加到ASP.NET MVC应用程序。

我只是试图添加一些基本的表单身份验证功能(由于简单和自定义数据库结构)

假设这是我的数据库结构:用户:用户名密码角色(最好是一些枚举,如果需要的话,字符串。目前,用户只有一个角色,但这可能会改变)

高层次的问题:鉴于上述数据库结构,我希望能够做到以下几点:

  • 使用表单认证进行简单登录
  • 装饰我的行动:[授权(角色= {MyRoles.Admin,MyRoles.Member})]
  • 在我的视图中使用角色(以确定在某些部分中显示的链接)
  • 目前,我真正确定的是如何进行身份验证。 之后,我迷路了。 我不知道我在哪一点获取用户角色(登录,每个授权?)。 由于我的角色可能不是字符串,我不确定他们将如何适应User.IsInRole()。

    现在,我在这里问,因为我没有找到一个“简单”完成我所需要的。 我见过很多例子。

    对于认证:

  • 我们有简单的用户验证来检查数据库和“SetAuthCookie”
  • 或者,我们重写成员供应商,这样做的ValidateUser内部在这两种,我不知道如何在我的简单的用户粘性的角色,让他们一起工作的:HttpContext.Current.User.IsInRole(“管理员”)此外,我不知道如何修改这个来处理我的枚举值。
  • 对于授权,我已经看到:

  • 派生AuthorizeAttribute并实现AuthorizeCore或OnAuthorization来处理角色?
  • 实施IPrincipal?
  • 任何援助将不胜感激。 不过,我担心我可能需要很多细节,因为我没有使用谷歌搜索似乎适合我需要做的事情。


    构建一个可以使用枚举而不是字符串的自定义AuthorizeAttribute 。 当需要授权时,通过追加枚举类型名称和枚举值并将枚举值从那里使用IsInRole ,将枚举转换为字符串。

    要将角色添加到授权用户中,您需要附加到HttpApplication AuthenticateRequest事件,如http://www.eggheadcafe.com/articles/20020906.asp中的第一个代码(但将大量嵌套的if语句转换为guard子句!) 。

    您可以将表单验证cookie中的用户角色进行往返,也可以每次从数据库中抓取他们。


    我想我已经实现了类似的东西。
    基于NerdDinner教程的我的解决方案如下。

    当你在用户中签名时 ,添加如下代码:

    var authTicket = new FormsAuthenticationTicket(
        1,                             // version
        userName,                      // user name
        DateTime.Now,                  // created
        DateTime.Now.AddMinutes(20),   // expires
        rememberMe,                    // persistent?
        "Moderator;Admin"                        // can be used to store roles
        );
    
    string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
    
    var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
    HttpContext.Current.Response.Cookies.Add(authCookie);
    

    将以下代码添加到Global.asax.cs

    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
    {
        HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
        if (authCookie == null || authCookie.Value == "")
            return;
    
        FormsAuthenticationTicket authTicket;
        try
        {
            authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        }
        catch
        {
            return;
        }
    
        // retrieve roles from UserData
        string[] roles = authTicket.UserData.Split(';');
    
        if (Context.User != null)
            Context.User = new GenericPrincipal(Context.User.Identity, roles);
    }
    

    完成此操作后,可以在控制器操作代码中使用[Authorize]属性:

    [Authorize(Roles="Admin")]
    public ActionResult AdminIndex ()
    

    如果您还有其他问题,请告诉我。


    我做了这样的事情:

  • 使用Global.asax.cs加载要在会话,高速缓存或应用程序状态中比较的角色,或在ValidateUser控制器上实时加载它们
  • 将[授权]属性分配给您的控制器,您想要授权

     [Authorize(Roles = "Admin,Tech")]
    

    或允许访问,例如Login和ValidateUser控制器使用下面的属性

     [AllowAnonymous] 
    

    我的登录表单

    <form id="formLogin" name="formLogin" method="post" action="ValidateUser">
    <table>
      <tr>
        <td>
           <label for="txtUserName">Username: (AD username) </label>
        </td>
        <td>
           <input id="txtUserName" name="txtUserName" role="textbox" type="text" />
        </td>
      </tr>
      <tr>
         <td>
             <label for="txtPassword">Password: </label>
         </td>
         <td>
             <input id="txtPassword" name="txtPassword" role="textbox" type="password" />
         </td>
      </tr>
      <tr>
          <td>
             <p>
               <input id="btnLogin" type="submit" value="LogIn" class="formbutton" />
            </p>
          </td>
      </tr>
    </table>
           @Html.Raw("<span id='lblLoginError'>" + @errMessage + "</span>")
    </form>
    

    从Form表单调用登录控制器和ValidateUser控制器

    验证用户是通过WCF服务进行验证,该服务可以针对服务本地的Windows AD Context进行验证,但您可以将其更改为您自己的验证机制

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Security;
    using System.Security.Principal;
    using MyMVCProject.Extensions;
    namespace MyMVCProject.Controllers
    {
    public class SecurityController : Controller
    {
        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
            Session["LoginReturnURL"] = returnUrl;
            Session["PageName"] = "Login";
            return View("Login");
        }
        [AllowAnonymous]
        public ActionResult ValidateUser()
        {
            Session["PageName"] = "Login";
            ViewResult retVal = null;
            string loginError = string.Empty;
            HttpContext.User = null;
    
            var adClient = HttpContext.Application.GetApplicationStateWCFServiceProxyBase.ServiceProxyBase<UserOperationsReference.IUserOperations>>("ADService").Channel;
    
            var username = Request.Form["txtUserName"];
            var password = Request.Form["txtPassword"];
    
            //check for ad domain name prefix
            if (username.Contains(@""))
              username = username.Split('')[1];
    
            //check for the existence of the account 
            var acctReq = new UserOperationsReference.DoesAccountExistRequest();
            acctReq.userName = username;
            //account existence result
            var accountExist = adClient.DoesAccountExist(acctReq);
            if (!accountExist.DoesAccountExistResult)
            {
                //no account; inform the user
                return View("Login", new object[] { "NO_ACCOUNT", accountExist.errorMessage });
            }
            //authenticate
            var authReq = new UserOperationsReference.AuthenticateRequest();
            authReq.userName = username;
            authReq.passWord = password;
            var authResponse = adClient.Authenticate(authReq);
            String verifiedRoles = string.Empty;
            //check to make sure the login was as success against the ad service endpoint
            if (authResponse.AuthenticateResult == UserOperationsReference.DirectoryServicesEnumsUserProperties.SUCCESS)
            {
                Dictionary<string, string[]> siteRoles = null;
    
                //get the role types and roles
                if (HttpContext.Application["UISiteRoles"] != null)
                    siteRoles = HttpContext.Application.GetApplicationState<Dictionary<string, string[]>>("UISiteRoles");
    
                string groupResponseError = string.Empty;
                if (siteRoles != null && siteRoles.Count > 0)
                {
                    //get the user roles from the AD service
                    var groupsReq = new UserOperationsReference.GetUsersGroupsRequest();
                    groupsReq.userName = username;
                    //execute the service method for getting the roles/groups
                    var groupsResponse = adClient.GetUsersGroups(groupsReq);
                    //retrieve the results
                    if (groupsResponse != null)
                    {
                        groupResponseError = groupsResponse.errorMessage;
                        var adRoles = groupsResponse.GetUsersGroupsResult;
    
                        if (adRoles != null)
                        {
                            //loop through the roles returned from the server
                            foreach (var adRole in adRoles)
                            {
                                //look for an admin role first
                                foreach (var roleName in siteRoles.Keys)
                                {
                                    var roles = siteRoles[roleName].ToList();
                                    foreach (var role in roles)
                                    {
                                        if (adRole.Equals(role, StringComparison.InvariantCultureIgnoreCase))
                                        {
                                            //we found a role, stop looking
                                            verifiedRoles += roleName + ";";
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (String.IsNullOrEmpty(verifiedRoles))
                {
                    //no valid role we need to inform the user
                    return View("Login", new object[] { "NO_ACCESS_ROLE", groupResponseError });
                }
    
                if (verifiedRoles.EndsWith(";"))
                    verifiedRoles = verifiedRoles.Remove(verifiedRoles.Length - 1, 1);
    
                //all is authenticated not build the auth ticket
                var authTicket = new FormsAuthenticationTicket(
                1,                             // version
                username,                      // user name
                DateTime.Now,                  // created
                DateTime.Now.AddMinutes(20),  // expires
                true,                    // persistent?
               verifiedRoles   // can be used to store roles
                );
    
                //encrypt the ticket before adding it to the http response
                string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
    
                var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                Response.Cookies.Add(authCookie);
    
                Session["UserRoles"] = verifiedRoles.Split(';');
    
                //redirect to calling page
                Response.Redirect(Session["LoginReturnURL"].ToString());
            }
            else
            {
                retVal = View("Login", new object[] { authResponse.AuthenticateResult.ToString(), authResponse.errorMessage });
            }
    
            return retVal;
        }
    }
    

    }

    用户现在通过身份验证创建新的身份

    protected void FormsAuthentication_OnAuthenticate(Object sender,     FormsAuthenticationEventArgs e)
        {
            if (FormsAuthentication.CookiesSupported == true)
            {
                HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
                if (authCookie == null || authCookie.Value == "")
                    return;
    
                FormsAuthenticationTicket authTicket = null;
                try
                {
                    authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                }
                catch
                {
                    return;
                }
    
                // retrieve roles from UserData
                if (authTicket.UserData == null)
                    return;
    
                //get username from ticket
                string username = authTicket.Name;
    
                Context.User = new GenericPrincipal(
                          new System.Security.Principal.GenericIdentity(username, "MyCustomAuthTypeName"), authTicket.UserData.Split(';'));
            }
        }
    

    在我的网站上我的_Layout.cshtml的顶部,我有这样的东西

     {
      bool authedUser = false;
      if (User != null && User.Identity.AuthenticationType == "MyCustomAuthTypeName" && User.Identity.IsAuthenticated)
       {
          authedUser = true;
       }
     }
    

    然后在体内

            @{
             if (authedUser)
              {
                <span id="loggedIn_userName">
                    <label>User Logged In: </label>@User.Identity.Name.ToUpper()
                </span>
              }
              else
              {
                <span id="loggedIn_userName_none">
    
                    <label>No User Logged In</label>
                </span>
              }
            }
    
    链接地址: http://www.djcxy.com/p/90161.html

    上一篇: ASP.NET MVC Forms Authentication + Authorize Attribute + Simple Roles

    下一篇: Alternative to Role Provider?