写在前面 Forms 认证即是表单认证,需提供身份 id 和密码 password 的进行认证和授权管理。
下面看看他的工作方式:
新建项目 创建一个 ASP.NET WEB 项目,勾选 MVC 和 WEB API
本案例使用的 MVC4 框架演示
打开 http://localhost:54125/ ,效果图:
Look,页面没有做任何权限控制,显示正常。
接下来给 HomeController/Index
加上 [Authorize]
特性
1 2 3 4 5 6 7 8 public class HomeController : Controller { [Authorize ] public ActionResult Index () { return View(); } }
[Authorize]
:指定对控制器或操作方法的访问只限于满足授权要求的用户。
[AllowAnonymous]
:表示一个特性,该特性用于标记在授权期间要跳过 System.Web.Mvc.AuthorizeAttribute 的控制器和操作。
访问 http://localhost:54125/
站点抛出异常 HTTP Error 401.0 - Unauthorized
提示我们没有查看权限,因为我们在上面给 Index
设置了权限认证
1 2 [Authorize ] public ActionResult Index ()
配置登录页 正常情况下,我们是不会抛出 401.01
黄页的
如果用户没有查看权限,我们会要求用户返回登录页完成认证操作
在 Web.Config
中启用 Forms 身份验证,并设置登录地址为 ~/Home/Login
在 system.web
节点中添加
1 2 3 4 <authentication mode ="Forms" > <forms loginUrl ="~/Home/Login" timeout ="2880" /> </authentication >
记得在 Home
控制器中添加 Login
登录页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public ActionResult Login (){ return View(); } [HttpPost ] public ActionResult Login (string returnUrl ){ if (Request.HttpMethod == "POST" ) { var userName = Request["userName" ]; var passWord = Request["passWord" ]; if (userName == "admin" && passWord == "123" ) { var ticket = new FormsAuthenticationTicket( 1 , userName, DateTime.Now, DateTime.Now.AddMinutes(20 ), true , "role1,role2,role3" , "/" ); var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket)) { HttpOnly = true }; HttpContext.Response.Cookies.Add(cookie); if (string .IsNullOrEmpty(returnUrl)) { return RedirectToAction("Index" ); } else { return Redirect(returnUrl); } } } ViewBag.ReturnUrl = returnUrl; return View(); }
Index.cshtml
视图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 @{ Layout = null; } <!DOCTYPE html > <html > <head > <meta name ="viewport" content ="width=device-width" /> <title > Login</title > </head > <body > <h1 > Login</h1 > <form method ="post" > <table > <tr > <td > userName</td > <td > <input name ="userName" value ="admin" /> </td > </tr > <tr > <td > passWord</td > <td > <input type ="password" name ="passWord" value ="123" /> </td > </tr > </table > <button type ="submit" > 登录</button > </form > </body > </html >
好的,我们在访问一下 http://localhost:54125/
如期跳转至认证页面!点击登录按钮,认证成功的话会跳回首页
好了,如愿显示!至此,简单权限认证完成了。
添加角色功能 前边只是做了简单的登录认证,如果项目要求权限的认证粒度比较细的话,就不能满足了。
IndexNeedRole4
只对某 role4
开放
1 2 3 4 5 [MyAuthorize(Roles = "role4" ) ] public ActionResult IndexNeedRole4 (){ return View(); }
我们需要新建用于验证角色和用户名的 Authorize
特性:MyAuthorize
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class MyAuthorizeAttribute : AuthorizeAttribute { protected override bool AuthorizeCore (System.Web.HttpContextBase httpContext ) { var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; var ticket = FormsAuthentication.Decrypt(cookie.Value); var roles = ticket.UserData; var inRoles = false ; foreach (var role in roles.Split(',' )) { if (Roles.Contains(role)) { inRoles = true ; break ; } } return inRoles; } }
代码加好了,我们再试试:http://localhost:54125/Home/IndexNeedRole4
返回正常,回到了权限认证界面。
点击登录,发现这个页面只是刷新了,所有 input
都清空了
这是正常的,因为在 Home/Login
里边登录逻辑的 ticket
角色只赋值了 role1,role2,role3
加上 role4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ··· if (userName == "admin" && passWord == "123" ){ var ticket = new FormsAuthenticationTicket( 1 , userName, DateTime.Now, DateTime.Now.AddMinutes(20 ), true , "role1,role2,role3,role4" , "/" ); ···
再次点击登录
OK, 如期显示正常
参考链接
理解 OAuth 2.0 - 阮一峰的网络日志
权限认证 - 随笔分类 - 漂亮的猫 - 博客园
权限认证机制 - 搬砖滴 - 博客园