以前项目的登录认证和权限管理总要做的很麻烦,现在MVC提供很便捷的方式。
主要思路:通过自定义属性Attribute的方式来控制,可全局过滤也可以针对部分Controler
1.首先自定义属性
1.登录认证(自定义CustomActionAttribute,继承ActionFilterAttribute)
public class CustomActionAttribute : ActionFilterAttribute
{
public bool IsCheck { get; set; }
HttpCookie httpCookie;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!IsCheck)
{
return;
}
httpCookie = filterContext.HttpContext.Request.Cookies["AuthToken"];
if (httpCookie == null)
{
filterContext.HttpContext.Response.Redirect("/Login/Index");
}
else
{
//将控制器返回的数据压缩
string acceptEcoding = filterContext.HttpContext.Request.Headers["Accept-Encoding"];
if (string.IsNullOrWhiteSpace(acceptEcoding))
{
return;
}
if (acceptEcoding.Contains("gzip"))
{
filterContext.HttpContext.Response.AppendHeader("content-encoding", "gzip");
filterContext.HttpContext.Response.Filter = new GZipStream(filterContext.HttpContext.Response.Filter, CompressionMode.Compress);
}
base.OnActionExecuting(filterContext);
}
}
}
2.权限管理(自定义CustomAuthorizeAttribute,继承AuthorizeAttribute)
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
HttpCookie httpCookie;
public override void OnAuthorization(AuthorizationContext filterContext)
{
httpCookie = filterContext.HttpContext.Request.Cookies["AuthToken"];
if (httpCookie == null)
{
filterContext.HttpContext.Response.Redirect("/Login/Index");
}
else
{
base.OnAuthorization(filterContext);
}
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
//在cookie中获取授权码
CookieDate model = new CookieDate();
model = JsonConvert.DeserializeObject<CookieDate>(httpCookie.Value);
if (model != null && Roles.Contains(model.Role.ToString()))
{
return true;
}
else
{
return false;
}
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
//个人觉得对于某个页面控制,只有某些Role可以进入时,应该在该控制器的Index上设置权限控制,而不是对其他方法控制,因为很多时候ajax访问
filterContext.HttpContext.Response.Redirect("/Other/NoPermission");
base.HandleUnauthorizedRequest(filterContext);
}
}
2.添加到过滤器
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//是否需要全局,若是全局则添加在此
filters.Add(new CustomActionAttribute() { IsCheck = true });
}
}
3.在Global中注册过滤器
protected void Application_Start()
{
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
}
4.在登录认证Controller中:
public class LoginController : Controller
{
// GET: Login
public ActionResult Index()
{
return View();
}
public ActionResult Login(string name, string pwd)
{
var response = new TopResponse();
if (!string.IsNullOrWhiteSpace(name) && !string.IsNullOrWhiteSpace(pwd))
{
//对登录信息进行验证
response = new TopResponse()
{
IsError = false,
Message = "登录成功"
};
//登录成功后将token写入cookie
CookieDate cookieDate = new CookieDate()
{
Role = name,
Token = ConfigurationManager.AppSettings["AuthToken"].ToString()
};
var cookie = new HttpCookie("AuthToken", JsonConvert.SerializeObject(cookieDate));
cookie.HttpOnly = true;//不允许前端js访问cookie
cookie.Expires = DateTime.Now.AddMinutes(2);//设置cookie过期时间
HttpContext.Response.Cookies.Add(cookie);
}
return Json(response);
}
}
public class TopResponse
{
public bool IsError { get; set; }
public string Message { get; set; }
}
public class CookieDate
{
public string Role { get; set; }
public string Token { get; set; }
}
5.在请求的Controller中:
[CustomAuthorize(Roles ="aa,bb,cc")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
通过在需要控制Controller或者Action上面写上属性,即可达到权限控制的作用。