ASP.NET MVC 如何使用 Form Authentication?

前言

.NET 的 Form Authentication 是一种基于表单的简单且灵活的身份验证机制,用户通过输入用户名和密码来登录应用程序,并且通过配置来控制用户访问权限。

在使用 Form Authentication 时,我们需要在 web.config 文件中配置身份验证和授权规则,以及指定登录页面和登出页面等设置。

当用户访问需要身份验证的页面时,系统会自动重定向到登录页面,用户输入正确的用户名和密码后,系统在验证用户身份后生成一个身份验证票据,在后续的操作中,使用这个票据来确定用户的身份。

Form Authentication 是 ASP.NET 中内置的身份验证机制,使用起来相对简单,不需要额外的库或工具。

总的来说,相比 JWT 身份验证,Form Authentication 具有简单易用、自定义性强等优点,但同时也存在 CSRF(跨站请求伪造)等安全风险,适合用在简单的 Web 应用中。

下面讲一讲如何在 ASP.NET MVC 项目中使用 Form Authentication?

Step By Step 步骤

  1. 创建一个 ASP.NET MVC 项目

  2. 打开 Web.config,配置使用 Form Authentication

    xml 复制代码
    <configuration>
    	<system.web>
    		<authentication mode="Forms">
    		  <forms name=".login" loginUrl="login" timeout="30" slidingExpiration="true" />
    		</authentication>
    		......
    	</system.web>
    	......
    </configuration>
  3. 增加一个Attribute类,继承自 AuthorizeAttribute,留意注释

    c# 复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace Ando.ERP.Client.Mvc.Attribute
    {
    	/// <summary>
    	/// 自定义身份验证特性
    	/// </summary>
    	public class CustomAuthorzieAttribute: AuthorizeAttribute
    	{
    		private string _controllerName = string.Empty;
    		private string _actionName = string.Empty;
    
    		/// <summary>
    		/// 重写基类的 OnAuthorization 方法 
    		/// 
    		/// OnAuthorization 是该类的总入口
    		/// </summary>
    		/// <param name="filterContext"></param>
    		public override void OnAuthorization(AuthorizationContext filterContext)
    		{
    			_controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
    			_actionName = filterContext.ActionDescriptor.ActionName;
    
    			base.OnAuthorization(filterContext);
    		}
    
    		/// <summary>
    		/// 重写基类的 AuthorizeCore 方法
    		/// OnAuthorization 会首先调用此方法进行处理
    		/// </summary>
    		/// <param name="httpContext"></param>
    		/// <returns></returns>
    		protected override bool AuthorizeCore(HttpContextBase httpContext)
    		{
    			//Login UI,Don't need authentication and return true
    			if (_controllerName.ToLower() == "login")
    			{
    				return true;
    			}
    
    			if (httpContext.Session["UserInfo"] == null || httpContext.User == null || !httpContext.User.Identity.IsAuthenticated)
    			{
    				return false;
    			}
    
    			return true;
    		}
    
    		/// <summary>
    		/// 重写基类的 HandleUnauthorizedRequest 方法
    		/// 当 AuthorizeCore 方法返回 false,OnAuthorization 会继续调用此方法进行处理
    		/// </summary>
    		/// <param name="filterContext"></param>
    		protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    		{
    			base.HandleUnauthorizedRequest(filterContext);
    		}
    	}
    }	
  4. 在 App_Start/FilterConfig.cs 中注册自定义的 CustomAuthorzieAttribute

    c# 复制代码
    using Ando.ERP.Client.Mvc.Attribute;
    using System.Web;
    using System.Web.Mvc;
    
    namespace Ando.ERP.Client.Mvc
    {
    	public class FilterConfig
    	{
    		public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    		{
    			filters.Add(new HandleErrorAttribute());
    			filters.Add(new CustomAuthorzieAttribute());
    		}
    	}
    }
  5. 新建登录控制器文件写登录方法如 LoginController.cs

    c# 复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Security;
    using Ando.ERP.Logger;
    using Ando.ERP.BLL;
    using Ando.ERP.BLL.Model;
    
    namespace Ando.ERP.Client.Mvc.Controllers
    {
    	/// <summary>
    	/// 登录模块
    	/// </summary>
    	public class LoginController : Controller
    	{
    		/// <summary>
    		/// Login UI
    		/// </summary>
    		/// <returns></returns>
    		public ActionResult Index()
    		{
    			// Go to Home page if has logged in
    			if (this.Session["UserInfo"] != null && this.User != null && this.User.Identity.IsAuthenticated)
    			{
    				return RedirectToAction("Index", "MainMenu"); 
    			}
    
    			// Else display Login page
    			return View();
    		}
    
    		/// <summary>
    		/// 登录 API
    		/// </summary>
    		/// <param name="userName"></param>
    		/// <param name="password"></param>
    		/// <returns></returns>
    		[HttpPost]
    		public ActionResult Login(string userName, string password)
    		{
    			string status, msg, reurl;
    			var userAuthentication = new BLL.UserAuth.UserAuthentication();
    			var userAuthResult = userAuthentication.Login(userName, password);
    			if (userAuthResult.LoginStatus)
    			{
    				FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(30), true, "Valid User", "/");
    				string HashTicket = FormsAuthentication.Encrypt(Ticket);
    				HttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket);
    				HttpContext.Response.Cookies.Add(UserCookie);
    				HttpContext.Session["UserInfo"] = userAuthResult;
    
    				status = "1";
    				msg = "sucessful!";
    				reurl = "";
    			}
    			else
    			{
    				status = "0";
    				msg = "登录失败!";
    				reurl = "";
    			}
    
    			return Json(new { status = status, msg = msg, data = userAuthResult, reurl = reurl });
    		}
    	}
    }	
  6. 在前端即可以通过 Ajax 之类的技术调用这个 API 进行登录,或者通过 Postman 进行测试。

相关推荐
枯萎穿心攻击4 小时前
ECS由浅入深第三节:进阶?System 的行为与复杂交互模式
开发语言·unity·c#·游戏引擎
小码编匠4 小时前
WPF 自定义TextBox带水印控件,可设置圆角
后端·c#·.net
水果里面有苹果4 小时前
17-C#的socket通信TCP-1
开发语言·tcp/ip·c#
程序员秘密基地5 小时前
基于html,css,vue,vscode,vs2022,asp.net,aspnet,.net,c#,mysql数据库,在线健身,俱乐部管理系统
前端·vue.js·后端·mysql·asp.net
wstcl8 小时前
让你的asp.net网站在调试模式下也能在局域网通过ip访问
后端·tcp/ip·asp.net
阿蒙Amon12 小时前
C# Linq to SQL:数据库编程的解决方案
数据库·c#·linq
iCxhust14 小时前
c# U盘映像生成工具
开发语言·单片机·c#
emplace_back16 小时前
C# 集合表达式和展开运算符 (..) 详解
开发语言·windows·c#
阿蒙Amon17 小时前
为什么 12 版仍封神?《C# 高级编程》:从.NET 5 到实战架构,进阶者绕不开的必修课
开发语言·c#