简体   繁体   English

ASP.net MVC中的自定义表单身份验证/授权方案

[英]Custom form authentication / Authorization scheme in ASP.net MVC

I am trying to create a custom authentication scheme in ASP.NET MVC using form authentication. 我正在尝试使用表单身份验证在ASP.NET MVC中创建自定义身份验证方案。 The idea that I might have different areas on the site that will be managed - approver are and general user area, and these will use different login pages, and so forth. 我可能会在站点上具有将要管理的不同区域的想法-批准人区域和一般用户区域,这些区域将使用不同的登录页面,依此类推。 So this is what I want to happen. 所以这就是我要发生的事情。

  1. User access restricted page (right now I have it protected with a customer AuthorizeAttribute) 用户访问受限制的页面(现在我已使用客户的AuthorizeAttribute保护它)
  2. User is redirected to a specific login page (not the one from Web.config). 用户被重定向到特定的登录页面(而不是Web.config的登录页面)。
  3. User credentials are verified (via custom databse scheme) and user logs in. 验证用户凭据(通过自定义数据库方案)并登录用户。

Would really appreciate any help with this!!! 非常感谢您的帮助!!!

This is what I what I have so far, and it doesn't work: 这是我到目前为止所拥有的,并且不起作用:

 public class AdministratorAccountController : Controller
{
    public ActionResult Login()
    {
        return View("Login");
    }

    [HttpPost]
    public ActionResult Login(AdministratorAccountModels.LoginModel model, string returnUrl)
    {
        if (ModelState.IsValid)
            if (model.UserName == "admin" && model.Password == "pass") // This will be pulled from DB etc
            {
                var ticket = new FormsAuthenticationTicket(1,               // version 
                                                           model.UserName,  // user name
                                                           DateTime.Now,    // create time
                                                           DateTime.Now.AddSeconds(30), // expire time
                                                           false,           // persistent
                                                           "");             // user data

                var strEncryptedTicket = FormsAuthentication.Encrypt(ticket);
                var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, strEncryptedTicket);
                Response.Cookies.Add(cookie);

                if (!String.IsNullOrEmpty(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction("Index", "Home");
                }
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

    [AdministratorAuthorize]
    public ActionResult MainMenu()
    {
        return View();
    }

    public class AdministratorAuthorizeAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            var authenCookie = httpContext.Request.Cookies.Get(FormsAuthentication.FormsCookieName);
            if (authenCookie == null) return false;

            var ticket = FormsAuthentication.Decrypt(authenCookie.Value);
            var id = new FormsIdentity(ticket);
            var astrRoles = ticket.UserData.Split(new[] { ',' });
            var principal = new GenericPrincipal(id, astrRoles);
            httpContext.User = principal;
            return true;
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            var model = new AdministratorAccountModels.LoginModel();
            var viewData = new ViewDataDictionary(model);

            filterContext.Result = new ViewResult { ViewName = "Login", ViewData = viewData };

        }
    }
}

I used a combination of code suggested by minus4 and my own code above to create this simplified scenario that might help someone else. 我结合使用minus4建议的代码和上面的我自己的代码来创建此简化的场景,可能会对其他人有所帮助。 I added some comments about things that confused me at first. 一开始我添加了一些让我感到困惑的评论。

 public class AdministratorAccountController : Controller
{
    public ActionResult Login()
    {
        return View("Login");
    }

    [HttpPost]
    public ActionResult Login(AdministratorAccountModels.LoginModel model, string returnUrl)
    {
        if (ModelState.IsValid)
            // Here you would call a service to process your authentication
            if (model.UserName == "admin" && model.Password == "pass")
            {
                // * !!! *
                // Creating a FromsAuthenticationTicket is what 
                // will set RequestContext.HttpContext.Request.IsAuthenticated to True
                // in the AdminAuthorize attribute code below
                // * !!! *
                var ticket = new FormsAuthenticationTicket(1, // version 
                                                           model.UserName, // user name
                                                           DateTime.Now, // create time
                                                           DateTime.Now.AddSeconds(30), // expire time
                                                           false, // persistent
                                                           ""); // user data, such as roles

                var strEncryptedTicket = FormsAuthentication.Encrypt(ticket);
                var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, strEncryptedTicket);
                Response.Cookies.Add(cookie);

                // Redirect back to the page you were trying to access
                if (!String.IsNullOrEmpty(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction("Index", "Home");
                }
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

    [AdminAuthorize]
    public ActionResult MainMenu()
    {
        return View();
    }

    public class AdminAuthorize : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!filterContext.RequestContext.HttpContext.Request.IsAuthenticated)
            {
                // Redirect to the needed login page
                // This can be pulled from config file or anything else
                filterContext.HttpContext.Response.Redirect("/AdministratorAccount/Login?ReturnUrl=" 
                                        + HttpUtility.UrlEncode(filterContext.HttpContext.Request.RawUrl));               
            }

            base.OnActionExecuting(filterContext);
        }
    }
}

okay here you go The Code 好的,这里您去了代码

in there you have ActionFilters folder ( AuthAccess.cs) Plugins Folder (security.cs (encrypt/decrypt cookie), SessionHandler.cs (all matters of login)) Controllers folder (BaseController.cs, and exampleController (show you how to use) and the loginTable SQL file. 在其中有ActionFilters文件夹(AuthAccess.cs)插件文件夹(security.cs(加密/解密cookie),SessionHandler.cs(所有登录问题))Controllers文件夹(BaseController.cs和exampleController(向您展示如何使用)和loginTable SQL文件。

i use mysql so you may need to amend, also i use subsonic so my model would come from there and would be in the empty models folder. 我使用mysql,所以您可能需要进行修改,同时我也使用subsonic,因此我的模型将来自该模型,并将位于空的models文件夹中。

really simple to use will leave it up for a while for you, enjoy 真的很简单,会为您留下一阵子,享受

nope cookie model is here sorry: nope cookie模型在这里对不起:

using System;

namespace TestApp.Models
{
    public class CookieModel
{
    public string CurrentGuid { get; set; }
    public DateTime LoginTime { get; set; }
    public Int32 UserLevel { get; set; }
    public Int32 LoginID { get; set; }
    public bool isValidLogin { get; set; }
    public string realUserName { get; set; }
    public string emailAddress { get; set; }
}
}

Isn't this what roles are for? 这不是什么角色吗? Have a look at asp.net mvc authorization using roles or have a look at roles in general 看看使用角色的asp.net mvc授权或一般看一下角色

i tackled this one before i have a class i use for login 我在上课前要先解决这个问题

routines are login, read cookie, check cookie and they have a model that contains 例程是登录,读取cookie,检查cookie,并且它们的模型包含

name, email, id, userlevel 名称,电子邮件,ID,用户级别

then you just have your own custom actionFilter 那么你只有自己的自定义actionFilter

eg [CustomAuth(MinAllowedLevel=10)] 例如[CustomAuth(MinAllowedLevel = 10)]

i use a baseclass for all my controllers so i can have an easier link to all my session content and can then get info like so 我为所有控制器使用了基类,因此我可以更轻松地链接到所有会话内容,然后可以像这样获取信息

var model = pictures.all().where(x => x.userid == users.ReadCookie.userID)

i will bob up the code tommorow if you want for you when im back on UK daytime 当我回到英国白天时,如果您愿意,我会取消代码明天

say 10 hrs i will let you have the class for all the session stuff and the custom action filter that you can use, then all you need is a logins table with a userlevel field, best with levels of 10,20,30,40 incase you need a level between 1 and 2 说10个小时,我将为您提供所有会话内容的类以及您可以使用的自定义操作过滤器,那么您所需要的只是一个带有用户级别字段的登录表,最好是10,20,30,40个级别您需要一个介于1和2之间的水平

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM