MVC授权登录以访问操作

时间:2015-06-30 18:59:05

标签: asp.net-mvc authorize

我一直在试图寻找答案,但我似乎无法取得任何进展。

我想做的就是检查一个正确的用户名和密码组合,然后给予用户授权以访问用[Authorize]标签装饰的MVC动作。

    public ActionResult DoLogin(PageInitModel model)
    {
        EF_db db = new EF_db();

        string saltPassword = getSaltedPasswordEncryption(model.UserName, model.Password);

        var user = (from s in db.Users
                    where s.Username == model.UserName
                    && s.Password == saltPassword
                    select s).FirstOrDefault();

        if(user == null)
        {
            model.LoginFail = true;
            return View("Login", model);
        }
        else
        {
            //
            // give the user some magical token to access [Authorize] actions here
            //
            return RedirectToAction("Index", "Menu");
        }
    }

以上是登录操作(从基本表单调用),以下是我想限制访问的操作之一:

    public class MenuController : Controller
    {
        [Authorize]
        public ActionResult Index()
        {
            var pageInitModel = new PageInitModel();

            return View("Menu",pageInitModel);
        }
    }

我想自己跟踪用户(在我自己的表中),因为我想跟踪许多其他属性。我不确定我是否需要编写自定义的AuthorizeAttribute,或者是什么,但我似乎无法取得任何进展。

非常感谢任何帮助我指明正确方向的帮助。

谢谢!

3 个答案:

答案 0 :(得分:1)

您应该查看ASP.NET身份。请注意,这是在ASP.NET 5(?)中引入的,并取代了Microsoft已经使用的基本成员资格等旧框架。

老实说,你真的不想自己动手。 ASP.NET Identity完全按照您开箱即用的描述。请记住,身份验证和授权有两个不同的概念。

身份验证正在验证用户是否是他所说的人 授权仅限制访问“允许”的用户。

构建授权的方法有很多,但我认为基于角色的授权可以满足您的需求。您将定义多个角色,例如用户,管理员,主持人,管理员等。

然后,您可以根据角色限制对操作的访问。您甚至可以使角色重叠,并允许单个用户拥有多个角色。最终结果是,一旦用户登录他们的角色,就可以通过授权标签确定他们可以做什么。

[Authorize(Roles="Admin")]

如果用户未登录,他们将被重定向到登录表单AUTHENTICATE(“嗯我不知道你是谁”。一旦通过身份验证,如果他们未获得授权他们将仍被限制在此行动(“哦,我知道你是谁,但你不能这样做”。

要完善它,您还可以进行匿名操作,这意味着不需要身份验证,并授权不限于特定角色的操作(允许任何经过身份验证的用户,但不允许未经身份验证的用户)。

即使使用基本的[授权]您遇到问题,也要相信即使是身份验证也存在一些配置问题。我建议通过一个教程构建一个像这样的示例应用程序: http://blogs.msdn.com/b/webdev/archive/2013/10/20/building-a-simple-todo-application-with-asp-net-identity-and-associating-users-with-todoes.aspx

答案 1 :(得分:0)

据我了解,您拥有自己的用户信息,并且您可能希望使用自定义代码进行身份验证。但要实际登录用户,您必须创建用户会话(Cookie会话)以进一步验证请求。

您已验证用户名和密码。现在您可以使用表单身份验证创建会话cookie。以下是您第一个问题的答案:

  

//为用户提供一些神奇的令牌来访问[授权]操作

// User name and password matches
if (userValid)
    {

        FormsAuthentication.SetAuthCookie(username, false);
        if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
            && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
        {
            return Redirect(returnUrl);
        }
        else
        {
            return RedirectToAction("Index", "Home");
        }
    }

Authorize属性将检查针对该操作的请求是否已通过身份验证。此属性在内部检查会话cookie是否有效并经过身份验证。

此属性不仅会检查身份验证,还可以验证授权。因此,您可以使用自定义角色和“授权”属性来限制用户访问特定视图/操作。

答案 2 :(得分:0)

有人向我指出,我需要查看cookie或现有会员提供商,所以我浏览了FormsAuthenticationTickets并推出了我自己喜欢的反馈解决方案。

当使用FormsAuthenticationTicket类成功登录时,我最终创建了一个新票证(见下文)。

            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
                user.Username,
                DateTime.Now,
                DateTime.Now.AddHours(2),
                false,
                userData,
                FormsAuthentication.FormsCookiePath);

            // Encrypt the ticket.
            string encTicket = FormsAuthentication.Encrypt(ticket);

            // Create the cookie.
            Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)); 

然后我写了一个自定义的ActionFilter,所以我可以创建自己的方法装饰器(或者他们所称的任何东西)。

namespace MyApp.Filters
{
    public class CustomLoginFilter : ActionFilterAttribute, IActionFilter
    {
        void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Retrieves the cookie that contains your custom FormsAuthenticationTicket.
            HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

            if (authCookie != null)
            {
                // There's actually a cookie
                // Decrypts the FormsAuthenticationTicket that is held in the cookie's .Value property.
                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

                 if (authTicket != null && user != null && data == authTicket.UserData)
                 {
                     // Everything looks good
                     this.OnActionExecuting(filterContext);
                 }
                 else
                 {
                    //log bounceback - someone screwed with the cookie
                    filterContext.Result = new RedirectToRouteResult(
                    new RouteValueDictionary 
                    { 
                        { "controller", "Login" }, 
                        { "action", "Index" } 
                    });
                 }
            }
            else
            {
                //log bounceback - not logged in
                filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary 
                { 
                    { "controller", "Login" }, 
                    { "action", "Index" } 
                });
            }
        }
    }
}

我可能会更多地使用它,但它现在似乎工作正常。

感谢您的帮助。