http://www.cnblogs.com/freeliver54/p/3792410.html
在开发过程中,需要用户登陆才能访问指定的页面这种功能,微软已经提供了这个特性。
// 摘要:
// 表示一个特性,该特性用于限制调用方对操作方法的访问。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true , AllowMultiple = true )]
public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
但是,美中不足的是,需要微软自带的一些用户验证的东西,比如数据库,配置等等的。
常常我们只需要用SESSION或者Cookies去保存用户登录状态的时候,这岂不是杀鸡用牛刀的感觉?
那么,我们按照微软官方的这个特性,重写一个属于自己的验证特性类就行了。下面是我常用的自己写的一段代码,希望大家用得开心,如果有异议可以自己修改,代码无版权,哈哈,我们只为共享。下面也提供了一个可以直接引用的DLL,需要.NET 4.0 Framework的支持。
下载地址:
点击这里下载
代码:
using System.Web.Mvc;
namespace System
{
/// <summary>
/// 表示需要用户登录才可以使用的特性
/// <para> 如果不需要处理用户登录,则请指定AllowAnonymousAttribute属性 </para>
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true , AllowMultiple = true )]
public class AuthorizationAttribute : FilterAttribute, IAuthorizationFilter
{
/// <summary>
/// 默认构造函数
/// </summary>
public AuthorizationAttribute()
{
String authUrl = System.Configuration.ConfigurationManager.AppSettings[" AuthUrl " ];
String saveKey = System.Configuration.ConfigurationManager.AppSettings[" AuthSaveKey " ];
String saveType = System.Configuration.ConfigurationManager.AppSettings[" AuthSaveType " ];
if (String.IsNullOrEmpty(authUrl))
{
this ._AuthUrl = " /User/Login " ;
}
else
{
this ._AuthUrl = authUrl;
}
if (String.IsNullOrEmpty(saveKey))
{
this ._AuthSaveKey = " LoginedUser " ;
}
else
{
this ._AuthSaveKey = saveKey;
}
if (String.IsNullOrEmpty(saveType))
{
this ._AuthSaveType = " Session " ;
}
else
{
this ._AuthSaveType = saveType;
}
}
/// <summary>
/// 构造函数重载
/// </summary>
/// <param name="loginUrl"> 表示没有登录跳转的登录地址 </param>
public AuthorizationAttribute(String authUrl)
: this ()
{
this ._AuthUrl = authUrl;
}
/// <summary>
/// 构造函数重载
/// </summary>
/// <param name="loginUrl"> 表示没有登录跳转的登录地址 </param>
/// <param name="saveKey"> 表示登录用来保存登陆信息的键名 </param>
public AuthorizationAttribute(String authUrl, String saveKey)
: this (authUrl)
{
this ._AuthSaveKey = saveKey;
this ._AuthSaveType = " Session " ;
}
/// <summary>
/// 构造函数重载
/// </summary>
/// <param name="authUrl"> 表示没有登录跳转的登录地址 </param>
/// <param name="saveKey"> 表示登录用来保存登陆信息的键名 </param>
/// <param name="saveType"> 表示登录用来保存登陆信息的方式 </param>
public AuthorizationAttribute(String authUrl, String saveKey, String saveType)
: this (authUrl, saveKey)
{
this ._AuthSaveType = saveType;
}
private String _AuthUrl = String.Empty;
/// <summary>
/// 获取或者设置一个值,改值表示登录地址
/// <para> 如果web.config中未定义AuthUrl的值,则默认为/User/Login </para>
/// </summary>
public String AuthUrl
{
get { return _AuthUrl.Trim(); }
set
{
if (String.IsNullOrEmpty(value))
{
throw new ArgumentNullException(" 用于验证用户登录信息的登录地址不能为空! " );
}
else
{
_AuthUrl = value.Trim();
}
}
}
private String _AuthSaveKey = String.Empty;
/// <summary>
/// 获取或者设置一个值,改值表示登录用来保存登陆信息的键名
/// <para> 如果web.config中未定义AuthSaveKey的值,则默认为LoginedUser </para>
/// </summary>
public String AuthSaveKey
{
get { return _AuthSaveKey.Trim(); }
set
{
if (String.IsNullOrEmpty(value))
{
throw new ArgumentNullException(" 用于保存登陆信息的键名不能为空! " );
}
else
{
this ._AuthSaveKey = value.Trim();
}
}
}
private String _AuthSaveType = String.Empty;
/// <summary>
/// 获取或者设置一个值,该值表示用来保存登陆信息的方式
/// <para> 如果web.config中未定义AuthSaveType的值,则默认为Session保存 </para>
/// </summary>
public String AuthSaveType
{
get { return _AuthSaveType.Trim().ToUpper(); }
set
{
if (String.IsNullOrEmpty(value))
{
throw new ArgumentNullException(" 用于保存登陆信息的方式不能为空,只能为【Cookie】或者【Session】! " );
}
else
{
_AuthSaveType = value.Trim();
}
}
}
/// <summary>
/// 处理用户登录
/// </summary>
/// <param name="filterContext"></param>
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext == null )
{
throw new Exception(" 此特性只适合于Web应用程序使用! " );
}
else
{
switch (AuthSaveType)
{
case " SESSION " :
if (filterContext.HttpContext.Session == null )
{
throw new Exception(" 服务器Session不可用! " );
}
else if (!filterContext.ActionDescriptor.IsDefined(typeof (AllowAnonymousAttribute), true )
&& !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof (AllowAnonymousAttribute), true ))
{
if (filterContext.HttpContext.Session[_AuthSaveKey] == null )
{
filterContext.Result = new RedirectResult(_AuthUrl);
}
}
break ;
case " COOKIE " :
if (!filterContext.ActionDescriptor.IsDefined(typeof (AllowAnonymousAttribute), true )
&& !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof (AllowAnonymousAttribute), true ))
{
if (filterContext.HttpContext.Request.Cookies[_AuthSaveKey] == null )
{
filterContext.Result = new RedirectResult(_AuthUrl);
}
}
break ;
default :
throw new ArgumentNullException(" 用于保存登陆信息的方式不能为空,只能为【Cookie】或者【Session】! " );
}
}
}
}
}
然后在Web.Config文件里面加入下面几句用于配置登陆验证的一些信息:
<appSettings>
<add key=" AuthUrl " value=" /User/Login " />
<add key=" AuthSaveKey " value=" LoginedUser " />
<add key=" AuthSaveType " value=" Session " />
</appSettings>
使用实例:
// ...省略引用
namespace MrHuo.Framework.Blog
{
[Authorization] // 如果将此特性加在Controller上,那么访问这个Controller里面的方法都需要验证用户登录状态
public class UserController:Controller
{
[AllowAnonymous] // 这里是一个特例,有这个特性,表示这个方法不需要验证用户登录状态
public ActionResult Index()
{
// ...省略具体代码
}
// 这里的方法需要验证登录状态,以下雷同
public ActionResult Create()
{
// ...省略具体代码
}
}
}
评论
MVC session过期如何处理跳转
http://www.cnblogs.com/jenney-qiu/archive/2013/07/25/3213928.html
以前我们总是会写一个基类也叫父类来判断session是否已过期然后跳转到指定的错误页面或者登陆界面,然后让所有的页面都继承这个基类,但是当我们应用到MVC项目中时,发现该方法并不会起作用。这时我们可以这么做:
1.建一个类,如下
using System;
using System.Web.Mvc;
using System.Web.Routing;
namespace CheckInManagerSystem.Controllers
{
public class CheckLogin : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Session != null)
{
if (filterContext.HttpContext.Session.IsNewSession)
{
var sessionCookie = filterContext.HttpContext.Request.Headers["Cookie"];
if ((sessionCookie != null) && (sessionCookie.IndexOf("ASP.NET_SessionId", StringComparison.OrdinalIgnoreCase) >= 0))
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Controller = "Account", Action = "LogOff" }));//这里是跳转到Account下的LogOff,自己定义
}
}
}
}
}
}
2.在每个用到session的Action前增加这个[CheckLogin()],如
[CheckLogin()]
public ActionResult Details(int userid)
{
ViewDataLoad();
return View(_context.GetUserById(userid));
}
这样就OK啦!不会再因为session过期而报红页面了!
MVC中利用Filter验证用户登录状态
http://blog.csdn.net/xyzqiang/article/details/7327119
第一步,建立Filter类
[csharp] view plaincopy
01.public class CheckinLoginAttribute:ActionFilterAttribute
02. {
03. public override void OnActionExecuting(ActionExecutingContext filterContext)
04. {
05. if (filterContext.HttpContext.Session["user"] == null)
06. {
07. filterContext.HttpContext.Response.Redirect("/User/Login");
08. }
09. }
10. }
第二步,在需要验证的Action上加上Filter
[csharp] view plaincopy
01.public class HomeController : Controller
02. {
03. //
04. // GET: /Home/
05.
06. [CheckinLogin]
07. public ActionResult Index()
08. {
09. return View();
10. }
11.
12. }
直接用Response.Redirect("default.aspx")的话当然验证失败,因为你根本没有建立身份验证票。FormsAuthentication.RedirectFromLoginPage方法,会自动完成很多功能的。如完成生成身份验证票,写回客户端,浏览器重定向等一系列的动作。当然完成这些功能并不是只有FormsAuthentication.RedirectFromLoginPage方法才能办到,相反如果需要带角色信息的验证则只能采用其他办法。
我门可采用手动添加身份验证票
1.FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket (1,"coffee",DateTime.Now, DateTime.Now.AddMinutes(20), false,UserRoles,"/") ;
2.加密序列化
string HashTicket = FormsAuthentication.Encrypt (Ticket) ;
3.生成cookie
HttpCookie UserCookie = new HttpCookie(FormsAuthentication.FormsCookieName, HashTicket) ;
4.身份验证票Cookie输出到客户端
Response.Cookies.Add(UserCookie)
5.重定向
Response.Redirect (Context.Request["ReturnUrl"]) ;
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, // Ticket version
userCode, // Username to be associated with this ticket
DateTime.Now, // Date/time issued
DateTime.Now.AddMinutes(30), // Date/time to expire
true, // "true" for a persistent user cookie (could be a checkbox on form)
UserPrincipal.CreateUserData(staffId), // User-data (the roles from the user record)
FormsAuthentication.FormsCookiePath);
// Hash the cookie for transport over the wire
string hash = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(
FormsAuthentication.FormsCookieName, // Name of auth cookie
hash); // Hashed ticket
// Add the cookie to the list for outbound response
Response.Cookies.Add(cookie);
Response.Redirect(this.Request.QueryString["ReturnUrl"]);