Authorization.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using System;
  2. using System.Web.Mvc;
  3. namespace CommonTool
  4. {
  5. /// <summary>
  6. /// 表示需要用户登录才可以使用的特性
  7. /// <para>如果不需要处理用户登录,则指定AllowAnonymousAttribute属性</para>
  8. /// </summary>
  9. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
  10. public class AuthorizationAttribute : FilterAttribute, IAuthorizationFilter
  11. {
  12. #region 使用方法
  13. // 在Web.Config文件里面加入下面几句用于配置登陆验证的一些信息:
  14. // <appSettings>
  15. // <add key = "AuthUrl" value="/User/Login" />
  16. // <add key = "AuthSaveKey" value="LoginedUser" />
  17. // <add key = "AuthSaveType" value="Session" />
  18. // </appSettings>
  19. //使用实例:
  20. ////...省略引用
  21. //namespace MrHuo.Framework.Blog
  22. // {
  23. // [Authorization]//如果将此特性加在Controller上,那么访问这个Controller里面的方法都需要验证用户登录状态
  24. // public class UserController : Controller
  25. // {
  26. // [AllowAnonymous]//这里是一个特例,有这个特性,表示这个方法不需要验证用户登录状态
  27. // public ActionResult Index()
  28. // {
  29. // //...省略具体代码
  30. // }
  31. // //这里的方法需要验证登录状态,以下雷同
  32. // public ActionResult Create()
  33. // {
  34. // //...省略具体代码
  35. // }
  36. // }
  37. //}
  38. #endregion
  39. #region 构造函数
  40. /// <summary>
  41. /// 默认构造函数
  42. /// </summary>
  43. public AuthorizationAttribute()
  44. {
  45. string authUrl = System.Configuration.ConfigurationManager.AppSettings["AuthUrl"];
  46. string authSaveKey = System.Configuration.ConfigurationManager.AppSettings["AuthSaveKey"];
  47. string authSaveType = System.Configuration.ConfigurationManager.AppSettings["AuthSaveType"];
  48. _authUrl = string.IsNullOrEmpty(authUrl) ? "/User/Login" : authUrl;
  49. _authSaveKey = string.IsNullOrEmpty(authSaveKey) ? "LoginedUser" : authSaveKey;
  50. _authSaveType = string.IsNullOrEmpty(authSaveType) ? "Session" : authSaveType;
  51. }
  52. /// <summary>
  53. /// 构造函数重载
  54. /// </summary>
  55. /// <param name="authUrl">表示没有登录跳转的登录地址</param>
  56. public AuthorizationAttribute(string authUrl)
  57. : this()
  58. {
  59. _authUrl = authUrl;
  60. }
  61. /// <summary>
  62. /// 构造函数重载
  63. /// </summary>
  64. /// <param name="authUrl">表示没有登录跳转的登录地址</param>
  65. /// <param name="authSaveKey">表示登录用来保存登陆信息的键名</param>
  66. public AuthorizationAttribute(string authUrl, string authSaveKey)
  67. : this(authUrl)
  68. {
  69. _authSaveKey = authSaveKey;
  70. }
  71. /// <summary>
  72. /// 构造函数重载
  73. /// </summary>
  74. /// <param name="authUrl">表示没有登录跳转的登录地址</param>
  75. /// <param name="authSaveKey">表示登录用来保存登陆信息的键名</param>
  76. /// <param name="authSaveType">表示登录用来保存登陆信息的方式</param>
  77. public AuthorizationAttribute(string authUrl, string authSaveKey, string authSaveType)
  78. : this(authUrl, authSaveKey)
  79. {
  80. _authSaveType = authSaveType;
  81. }
  82. #endregion
  83. #region 字段属性
  84. private string _authUrl;
  85. /// <summary>
  86. /// 获取或者设置一个值,改值表示登录地址
  87. /// <para>如果web.config中未定义AuthUrl的值,则默认为/User/Login</para>
  88. /// </summary>
  89. public string AuthUrl
  90. {
  91. get { return _authUrl.Trim(); }
  92. set
  93. {
  94. if (string.IsNullOrEmpty(value))
  95. throw new ArgumentNullException($"用于验证用户登录信息的登录地址不能为空!");
  96. _authUrl = value.Trim();
  97. }
  98. }
  99. private string _authSaveKey;
  100. /// <summary>
  101. /// 获取或者设置一个值,改值表示登录用来保存登陆信息的键名
  102. /// <para>如果web.config中未定义AuthSaveKey的值,则默认为LoginedUser</para>
  103. /// </summary>
  104. public string AuthSaveKey
  105. {
  106. get { return _authSaveKey.Trim(); }
  107. set
  108. {
  109. if (string.IsNullOrEmpty(value))
  110. throw new ArgumentNullException($"用于保存登录信息的键名不能为空");
  111. _authSaveKey = value.Trim();
  112. }
  113. }
  114. private string _authSaveType;
  115. /// <summary>
  116. /// 获取或者设置一个值,该值表示用来保存登陆信息的方式
  117. /// <para>如果web.config中未定义AuthSaveType的值,则默认为Session保存</para>
  118. /// </summary>
  119. public string AuthSaveType
  120. {
  121. get { return _authSaveType.Trim(); }
  122. set
  123. {
  124. if (string.IsNullOrEmpty(value))
  125. throw new ArgumentNullException($"于保存登陆信息的方式不能为空,只能为【Cookie】或者【Session】!");
  126. _authSaveType = value.Trim();
  127. }
  128. }
  129. #endregion
  130. #region 实现接口方法
  131. /// <summary>
  132. /// 处理用户登录
  133. /// </summary>
  134. /// <param name="filterContext"></param>
  135. public void OnAuthorization(AuthorizationContext filterContext)
  136. {
  137. if (filterContext.HttpContext == null)
  138. throw new Exception("此特性只适合于Web应用程序使用");
  139. switch (AuthSaveType)
  140. {
  141. case "Session":
  142. if (filterContext.HttpContext.Session == null)
  143. throw new Exception("服务器Session不可用");
  144. if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) &&
  145. !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))
  146. if (filterContext.HttpContext.Session[_authSaveKey] == null)
  147. filterContext.Result = new RedirectResult(_authUrl);
  148. break;
  149. case "Cookie":
  150. if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) &&
  151. !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))
  152. if (filterContext.HttpContext.Request.Cookies[_authSaveKey] == null)
  153. filterContext.Result = new RedirectResult(_authUrl);
  154. break;
  155. default:
  156. throw new ArgumentNullException($"用于保存登陆信息的方式不能为空,只能为【Cookie】或者【Session】!");
  157. }
  158. }
  159. #endregion
  160. }
  161. }