MVC 5 中的自定义身份验证和授权






4.40/5 (23投票s)
在这里,我解释了如何创建自定义身份验证并将其映射到默认的过滤器,例如授权、角色等。
引言
在我们的项目中存在某些场景,我们需要使用自定义身份验证,而不是使用默认的MVC5 Asp.net Identity机制。 因此,在这里我将解释如何创建自定义身份验证并将其映射到默认的过滤器,例如授权、角色等。
步骤如下
- 打开 Visual Studio 创建一个新项目
2. 选择 ASP.NET 应用程序并为项目命名
3. 选择 MVC 模板
4. 加载项目后,创建一个名为 DAL 的新文件夹(在这里我们可以调用我们自定义的 User Authentication 实现方法)
5. 现在项目结构在解决方案资源管理器中看起来像下图
6. 在 DAL 层中添加两个类:User.cs 和 Repository.cs
7. 将以下代码粘贴到 User.cs 文件中
public class User
{
public string Email { get; set; }
public string Roles { get; set; }
public string Password { get; set; }
}
8. 将以下代码粘贴到 Repository.cs 文件中
public static class Repository
{
static List<User> users = new List<User>() {
new User() {Email="abc@gmail.com",Roles="Admin,Editor",Password="abcadmin" },
new User() {Email="xyz@gmail.com",Roles="Editor",Password="xyzeditor" }
};
public static User GetUserDetails(User user)
{
return users.Where(u => u.Email.ToLower() == user.Email.ToLower() &&
u.Password == user.Password).FirstOrDefault();
}
}
9. 打开Controllers文件夹中的“AccountController”。
10. 转到名为 Login(LoginViewModel model, string returnUrl) 的方法
从 Login 方法中删除以下代码
11. 将以下代码粘贴到 login 方法中
if (!ModelState.IsValid)
{
return View(model);
}
User user = new User() { Email=model.Email,Password=model.Password};
user = Repository.GetUserDetails(user);
if (user!=null)
{
FormsAuthentication.SetAuthCookie(model.Email, false);
var authTicket = new FormsAuthenticationTicket(1, user.Email, DateTime.Now, DateTime.Now.AddMinutes(20), false, user.Roles);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
HttpContext.Response.Cookies.Add(authCookie);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
- 转到 AccountController 本身中的 public ActionResult LogOff() 方法
将现有代码替换为以下代码
//
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
//AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
FormsAuthentication.SignOut();
return RedirectToAction("Index", "Home");
}
- 打开 Global.asax.cs 文件
粘贴以下方法
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
if (authTicket != null && !authTicket.Expired)
{
var roles = authTicket.UserData.Split(',');
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles);
}
}
}
现在,身份验证和角色所需的设置已完成。
让我们看看我们创建了什么以及我们将如何使用它们
1. 我们在 Repository.cs 类中创建了两个用户 Admin,Editor
2. 现在在 HomeController 的“Index”方法中,我们将仅授予“Admin”访问权限,对于“About”方法,将同时授予“Admin”和“Editor”访问权限。
首先用 [Authorize] 属性装饰 HomeController 以限制未经授权的访问,然后使用上述方法装饰其余的两个方法,并赋予相应的角色。
有关参考,请参见以下代码段
[Authorize]
public class HomeController : Controller
[Authorize(Roles = "Admin")]
public ActionResult Index()
{
return View();
}
[Authorize(Roles = "Admin,Editor")]
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
就这样,我们的应用程序已准备好进行自定义身份验证和授权。
现在让我们运行应用程序,由于我们已经用 [Authorize] 属性装饰了 HomeController,我们将首先获得登录页面,而不是默认的 HomeController Index 方法。
如果我们查看网址,它不会直接调用 Account/Login 方法,而是有一个额外的 ReturnUrl
https://:51581/
请参阅默认路由配置,如下所示
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
因此,当它直接转到 HomeController 时,它不会被验证,因此它会重定向到 AccountController 中的登录页面。现在输入我们创建的所需凭据。我正在输入管理员详细信息,即
现在,当我们单击登录按钮时,它将重定向到 HomeController 中的 Index 方法。
当我们在右下角看到时,它将从上下文中读取用户详细信息,并显示 Hello abc@gmail.com!
现在注销并输入编辑器的凭据。
当我们单击登录页面时,我们将看到相同的屏幕,但在右侧我们可以看到用户已通过身份验证(Hello xyz@gmail.com!),因为他无权调用 Index 方法,它将显示相同的页面。
现在只需将 Url 指向 HomeController,“About”方法,如下所示。
https://:51581/Home/About
我们将被重定向到所需的页面,因为“Editor”角色有权限,他可以访问 About Action 方法。