MVC Authorize授权
一、授权用户访问
1、配置根目录web.config:
在<system.web></system.web>节点中间增加authentication,可以参考sealed class FormsAuthentication的属性;
<authentication mode="Forms"> <forms loginUrl="~/SysAdmins/Index" defaultUrl="~/Home/Index" timeout="2800" /> </authentication>
限制匿名访问动作方法:
如果只允许特定用户,可以用[Authorize(Users="user1,user2")];
[Authorize] public ActionResult ChangePwd() { } [Authorize(Users="user1,user2")] public ActionResult ChangePwd() { }
限制控制器访问:
[Authorize] public class StudentController : Controller { }
2、从登录页访问:
如果未授权或授权过期,会自动跳转到根目录web.config所示loginUrl页面,加上参数ReturnUrl,ReturnUrl=目标页路径;
http://localhost:49551/SysAdmins/Index?ReturnUrl=%2fHome%2fIndex
如想改变参数ReturnUrl的名称,即把上述地址中ReturnUrl替换为redirect,可以修改根目录web.config中appSettings节点;
<appSettings> <add key="aspnet:FormsAuthReturnUrlVar" value="redirect" /> </appSettings>
loginUrl页面:
<div id="loginInput"> <div class="loginInfo" id="ItaInfo" style="text-align:center"></div> <div class="loginItem">用户名: <input type="text" id="txtUserId" class="loginItemText" name="LoginId" value="@Model.LoginId"/> </div> <div class="loginItem">密 码: <input type="password" id="txtPwd" class="loginItemText" name="LoginPwd" value="@Model.LoginPwd"/> </div> <div class="loginItem"> <input type="checkbox" id="remeberMe"name="remeberMe"/> <span>记住我</span> <img id="ibtnLogin" src="~/Images/btnLogin.png" style="border-width:0px;" /> </div> </div>
登录信息验证通过后,发放授权票证,并发送Cookies给浏览器;
如果没有特殊需要,如附带角色等,可以直接生成,其中持久 Cookie(跨浏览器会话保存的 Cookie),是指Cookie写入磁盘,关闭浏览器后再用同一款浏览器打开,仍然可以读取此Cookie,如果没有过期,可以随请求发送到服务器:如果使用别的浏览器打开,因为目录不同,是读取不到此Cookie的。
bool isPersistent = Request.Form["RemeberMe"] == "on" ? true : false;//勾选记住我 FormsAuthentication.SetAuthCookie(objSysAdmin.AdminName, isPersistent);
如果需要更多设置,可以分步生成:
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1 , objSysAdmin.AdminName, DateTime.Now, DateTime.Now.Add(FormsAuthentication.Timeout), false , objSysAdmin.LoginId.ToString()); string enTicket = FormsAuthentication.Encrypt(ticket); HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, enTicket) { HttpOnly = true, Secure = FormsAuthentication.RequireSSL, Domain = FormsAuthentication.CookieDomain, Path = FormsAuthentication.FormsCookiePath, }; bool isPersistent = Request.Form["RemeberMe"] == "on" ? true : false;//勾选记住我 if (isPersistent)//勾选记住我 { //默认为0,即只存在于浏览器内存,关闭浏览器后消失,需要持久存储时设置 authCookie.Expires = DateTime.Now.Add(FormsAuthentication.Timeout); } Response.Cookies.Remove(authCookie.Name); Response.Cookies.Add(authCookie);
登录成功后,根据ReturnUrl跳转到默认页,或者目标页,注意这里方法入口参数ReturnUrl不区分大小写;
if (string.IsNullOrEmpty(ReturnUrl)) { return Redirect(FormsAuthentication.DefaultUrl); } else { return Redirect(ReturnUrl); }
3、注销登录,清除授权:
原理是把票据Cookies过期时间改为当前时间之前,发送给浏览器,浏览器自动删除过期Cookies;
public ActionResult ExitSys() { FormsAuthentication.SignOut(); return Redirect(FormsAuthentication.LoginUrl); }
二、授权角色访问
1、设置允许特定角色访问:
[Authorize(Roles="admin,test")] public class StudentController : Controller { }
[Authorize(Roles="admin,test",Users="user1,user2")] public class StudentController : Controller { }
2、在登录成功后,把用户角色保存在票证的userData属性:
如果需要记录更多内容,可以把对象序列化,作为userData,考虑流量,尽量减少内容;
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket( 1,//票证的版本号 objSysAdmin.AdminName,//用户名 DateTime.Now,//票证发出的时间 DateTime.Now.Add(FormsAuthentication.Timeout),//票证过期时间 false , //是否将票证持久存储在cookie中 "admin");//角色
3、每次访问时,在服务端获取角色:
在根目录下找到Global.asax,重构MvcApplication(),为AuthenticateRequest或AuthorizeRequest事件绑定响应方法,此时已对当前请求进行身份验证;如果userData为序列化对象字符串,先反序列化为对象;
public MvcApplication() { AuthenticateRequest += new EventHandler(ApplicationAuthenticateRequest); } /// <summary> /// 获取当前用户角色 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void ApplicationAuthenticateRequest(Object sender, EventArgs e) { HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName]; if (authCookie == null || authCookie.Value == "") { return; } FormsAuthenticationTicket authTicket = null; try { authTicket = FormsAuthentication.Decrypt(authCookie.Value); } catch { return; } string[] roles = authTicket.UserData.Split(new char[] { ',' }); if (Context.User != null) { Context.User = new System.Security.Principal.GenericPrincipal(Context.User.Identity, roles); } }
或
public MvcApplication() { AuthorizeRequest += new EventHandler(ApplicationAuthorizeRequest); } protected void ApplicationAuthorizeRequest(Object sender, EventArgs e) { HttpApplication App = (HttpApplication)sender; HttpContext Ctx = App.Context; //获取本次Http请求相关的HttpContext对象 if (Ctx.Request.IsAuthenticated == true) //验证过的用户才进行role的处理 { FormsIdentity Id = (FormsIdentity)Ctx.User.Identity; FormsAuthenticationTicket Ticket = Id.Ticket; //取得身份验证票 string[] Roles = Ticket.UserData.Split(','); //将身份验证票中的role数据转成字符串数组 Ctx.User = new System.Security.Principal.GenericPrincipal(Id, Roles); //将原有的Identity加上角色信息新建一个GenericPrincipal表示当前用户,这样当前用户就拥有了role信息 } }
参考资料:
- https://blog.51cto.com/962410314/1604409
- https://blog.csdn.net/billy_chen_2013/java/article/details/52255785
- https://segmentfault.com/a/1190000019280749?utm_source=tag-newest

浙公网安备 33010602011771号