ASP.net MVC中的自定义表单身份验证/授权方案
我正在尝试使用表单身份验证在ASP.NET MVC中创建自定义身份验证方案。我的想法是,我可能会在网站上有不同的区域进行管理-审批人和一般用户区域,这些将使用不同的登录页面,等等。这就是我想要发生的ASP.net MVC中的自定义表单身份验证/授权方案,asp.net,asp.net-mvc,security,asp.net-mvc-2,authorization,Asp.net,Asp.net Mvc,Security,Asp.net Mvc 2,Authorization,我正在尝试使用表单身份验证在ASP.NET MVC中创建自定义身份验证方案。我的想法是,我可能会在网站上有不同的区域进行管理-审批人和一般用户区域,这些将使用不同的登录页面,等等。这就是我想要发生的 用户访问受限页面(现在我使用customer Authorized属性对其进行保护) 用户被重定向到特定的登录页面(不是Web.config中的登录页面) 验证用户凭据(通过自定义数据库方案)并登录用户 非常感谢您的帮助 这就是我目前所拥有的,但它不起作用: public class Admini
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 };
}
}
}
在我有一个用于登录的类之前,我解决了这个问题 例程包括登录、读取cookie、检查cookie,它们有一个包含 名称、电子邮件、id、用户级别 然后您就有了自己的自定义actionFilter 例如[CustomAuth(MinAllowedLevel=10)] 我的所有控制器都使用基类,因此我可以更轻松地链接到 我所有的会话内容,然后可以得到这样的信息
var model = pictures.all().where(x => x.userid == users.ReadCookie.userID)
如果你愿意的话,我明天回英国时会给你发代码
比如说10小时,我会让你上课,学习所有课程内容和课程
您可以使用自定义操作筛选器,然后您只需要一个带有userlevel字段的logins表,最好是10、20、30、40级别,以防您需要介于1和2之间的级别,这不是角色的用途吗? 看一看或看一看一般的角色好的,给你 其中有ActionFilters文件夹(AuthAccess.cs) 插件文件夹(security.cs(加密/解密cookie)、SessionHandler.cs(所有登录事项)) 控制器文件夹(BaseController.cs和exampleController)(演示如何使用) 和登录表SQL文件 我使用mysql,所以你可能需要修改,我也使用亚音速,所以我的模型将来自那里 并且会在空的models文件夹中 真正简单易用的软件会让你保留一段时间,好好享受吧 这里没有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; }
}
}
我使用了minus4建议的代码和上面我自己的代码的组合来创建这个简化的场景,这可能会帮助其他人
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);
}
}
}
嗯,不完全是这样,如果您的站点中有完全独立的登录区域,而这些区域不应该混合在一起,并且每个区域都需要不同的登录名,那么您就不能使用角色。例如,如果您有一个网站的管理员选项(任何访问者都不应该看到该选项)以及使用该网站的客户帐户。当您在未登录的情况下点击安全页面时,它会根据用户访问的区域将用户跳转到不同的登录屏幕。非常感谢,代码很有帮助。我做了一些更改以简化它并符合原始问题。这很酷是一个良好开端的基础快乐地帮助forms auth代码很棒。但有一点需要注意,我认为只有在url是本地的情况下才重定向到url是最佳做法。这可以降低重定向攻击的可能性。请参阅: