第一步 登录的时候写入标准的权限信息到Cookie中.
第二步 Global.asax 文件中增加从cookie中取得权限信息的代码
第三步 使用 [Authorize(Roles = “admin”)] 标注权限所需角色
[HttpPost]
public ActionResult DoLogin(string username, string password, string yzm, string returnUrl)
{
SysUser user = DB.FirstOrDefault(x => x.UserID == username && x.UserPassword == password);
if (Session["code"] != null && Session["code"].ToString().ToUpper().Trim().Equals(yzm.ToUpper()))
{
if (user != null)
{
// FormsAuthentication.SetAuthCookie(username, true);//比较差的方法,不能保存角色信息
SetFormsAuthentication(username,true, "admin");//admin 是角色名
//FormsAuthentication.SignOut();
if (!String.IsNullOrEmpty(returnUrl)) return Redirect(returnUrl);
else return Redirect("/");
}
else
{
ViewBag.Message = "用户名或密码错误!";
}
}
else
{
//登陆失败,提示错误信息
ViewBag.Message = "验证码错误!";
}
return View("Index");
}
//将登录信息写入Cookie
public void SetFormsAuthentication(string username, bool isPersistent, string roles)
{
roles = string.IsNullOrEmpty(roles) ? string.Empty : roles;
//创建票证
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
username,
DateTime.Now,
DateTime.Now.AddMinutes(720),
isPersistent,
roles,
FormsAuthentication.FormsCookiePath);
// 加密票证
string encTicket = FormsAuthentication.Encrypt(ticket);
// 创建cookie
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
{
HttpOnly = true,
Path = FormsAuthentication.FormsCookiePath,
Secure = false
};
if (ticket.IsPersistent)
{
cookie.Expires = ticket.Expiration;
}
Response.Cookies.Add(cookie);
}
Global.asax 文件中增加从cookie中恢复权限信息的代码,
public class MvcApplication : System.Web.HttpApplication
{
public MvcApplication()
{
AuthorizeRequest += new EventHandler(MvcApplication_AuthorizeRequest);
}
void MvcApplication_AuthorizeRequest(object sender, EventArgs e)
{
var url = Request.RawUrl;
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch (Exception ex)
{
return;
}
string[] roles = authTicket.UserData.Split(new char[] { ','});//如果存取多个角色,我们把它分解
FormsIdentity id = new FormsIdentity(authTicket);
GenericPrincipal principal = new GenericPrincipal(id, roles);
Context.User = principal;//存到HttpContext.User中
}
}
第三步 使用, 只需要在每个Action上面 加个注解属性. [Authorize(Roles = “admin”)]
这样只有是admin角色的用户才能访问. 这是 Authorize 类中定义的.
public class DefaultController : Controller
{
// GET: Default
[Authorize(Roles = "admin")] //这样用就可以了. admin 是角色名
public ActionResult Index()
{
return View();
}
}
看到这里, 估计有些人会觉得这个有点鸡肋. 我们设计系统的时候肯定不知道角色有那些的, 这样就把角色的个数框定死在代码里了.
有没有什么方法能够使得后期的角色可以动态增加, 而不修改系统呢?
经过修改,确实是可以做到的. 使用方法如下.
public class DefaultController : Controller
{
// GET: Default
//[App_Start.MVC.Filters.UserAuthorize( RightName ="121")]
[RightAuthorize(NeedRightId = "CustomeView", RightDesc= "查看客户信息")]
public ActionResult Index()
{
return View();
}
}
RightAuthorize这个类是自定定义的, 只需要继承自AuthorizeAttribute 就可以了.
using Common;
using MK.DBModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MKDataCenter
{
/// <summary>
/// 所需权限属性
/// </summary>
public class RightAuthorize : AuthorizeAttribute
{
/// <summary>
/// 权限注释,可通过反射自动添入到权限系统中.方便用户查看.
/// </summary>
public string RightDesc { get; set; }
/// <summary>
/// 访问本Action所需权限Id
/// </summary>
public string NeedRightId { get; set; }
/// <summary>
/// 权限列表
/// </summary>
private List<SysRoleRightRelation> Rights ;
private static ICache AllRightsCache = new SystemCache();
/// <summary>
/// 请求授权时执行
/// </summary>
public override void OnAuthorization(AuthorizationContext filterContext)
{
// 判断是否已经验证用户
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
// 如果没有验证则跳转到LogOn页面
filterContext.HttpContext.Response.Redirect("~/BaseApp/Login/Index");
return;
}
var ticket = ((System.Web.Security.FormsIdentity)filterContext.HttpContext.User.Identity).Ticket;
var roles = ticket.UserData.Split(',');
//去缓存查数据
var allRights = AllRightsCache.GetCache<List<MK.DBModel.SysRoleRightRelation>>("AllRights");
if (allRights == null)
{
//重新加载缓存权限数据
allRights = new DbHelp.Base.DbBase<SysRoleRightRelation>().AsQueryable().ToList();
AllRightsCache.SetCache("AllRights", allRights);
}
this.Rights = allRights
.Where( a=>roles.Contains( a.RoleID ) )
.ToList();
base.OnAuthorization(filterContext);
}
/// <summary>
/// 自定义授权检查(返回False则授权失败)
/// </summary>
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext.User.Identity.IsAuthenticated)
{
return this.Rights.Where(a=>a.RightID == this.NeedRightId).Count()>0;
}
else
{
//进入HandleUnauthorizedRequest
return false;
}
}
/// <summary>
/// 处理授权失败的HTTP请求
/// </summary>
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result = new ViewResult { ViewName = "AuthorizationFailView" };
}
}
}