ASP.NET MVC :MVC页面验证与授权
2008-07-09 22:22
465 查看
在ASP.NETMVC中,如何来实现表单的验证与授权访问呢?至少在CTP3中,还没有一个官方的解决方案。ASP.NETWebForm的表单验证和授权机制是否适合在ASP.NETMVC中使用呢?带着这些问题来进入我们今天的主题。
在ASP.NETWebForm的架构下,我们可以通过一定的配置即可实现用户身份验证和授权。特别是在ASP.NET2.0的Membership功能的支撑下,可以做到更加简洁可复用的用户验证系统。通过web.config可以做到对页面或目录对不同用户身份可见性的定制,但是它是基于物理文件和目录。而在ASP.NETMVC架构下,用户访问的每一个页面在磁盘中并没有一个固定的物理文件,它是通过Controller控制数据与视图的组合来生成HTML代码,进而向客户端输出。那么我们该如何来复用已有的表单验证授权机制呢?
在MVC中,请求的功能入口是Controller相应的Action函数,我们可以在函数执行前去控制请求权限。在ASP.NETMVCPreview2后,提供了一个机制让我们可以对Action的AOP拦截,这个接口定义如下:
我们有两种方式来实现拦截,一种我们可以通过定义Attribute来实现拦截的功能,在System.Web.Mvc程序集中有一个ActionFilterAttribute抽象类,通过重写这个抽象类的这些虚方法,我们就可以实现对特定的执行过程进行拦截。
另一种方法,我们注意到Controller这个类也实现了IActionFilter这个接口,并且也提供了这四个函数的虚拟方法定义。框架内部,在调用Action方法的时候同时来调用这些拦截方法。具体的可以参考:ControllerActionInvoker这个类的实现,所有的Action的调用都在这个类当中被实现。所以我们只要重写Controller里这四个虚方法,也可完成本Controller面的所有Action的拦截。
在这里,我也找到了国外友人已经实现好的基于角色的MVC权限控制的方案。自定义了两个自定义Attribute,分别为:RequiresAuthenticationAttribute和RequiresRoleAttribute。通过这两个Attribute来可以作用于Class和Method,用标记哪些Controller或Action需要登录后,或者需要拥有哪些角色才能执行。如果用户没有拥有访问当然Controller或Action权限的时候,就会自动被重定向到登录页面去。下面是两个类的定义:
如上所介绍的两种方法,我们一样可以定义一个Controller基类,通过拦截来进行权限的控制。但是与定义Attribute相比,手法并不是很好,也不利于通用化。但是就理论上的性能来说,会比Attribute更好。
到目前为止,ASP.NETMVC还没有更新的消息,我想在正式版本的ASP.NETMVC框架,权限控制问题会有一个官方说法。希望到时候会有一种更为灵活和可配置的方案。也许通过控制Url来控制访问权限也是一种可行的方案,会不会集成到RouteTable里面呢?让我们试目以待吧。
上一篇:ASP.NETMVC:从ASP.NETWebForm到ASP.NETMVC技术上的共用和差异
广告:我的基于MVC的网站
在ASP.NETWebForm的架构下,我们可以通过一定的配置即可实现用户身份验证和授权。特别是在ASP.NET2.0的Membership功能的支撑下,可以做到更加简洁可复用的用户验证系统。通过web.config可以做到对页面或目录对不同用户身份可见性的定制,但是它是基于物理文件和目录。而在ASP.NETMVC架构下,用户访问的每一个页面在磁盘中并没有一个固定的物理文件,它是通过Controller控制数据与视图的组合来生成HTML代码,进而向客户端输出。那么我们该如何来复用已有的表单验证授权机制呢?
在MVC中,请求的功能入口是Controller相应的Action函数,我们可以在函数执行前去控制请求权限。在ASP.NETMVCPreview2后,提供了一个机制让我们可以对Action的AOP拦截,这个接口定义如下:
1:publicinterfaceIActionFilter
2:{
3:voidOnActionExecuted(ActionExecutedContextfilterContext);
4:voidOnActionExecuting(ActionExecutingContextfilterContext);
5:voidOnResultExecuted(ResultExecutedContextfilterContext);
6:voidOnResultExecuting(ResultExecutingContextfilterContext);
7:}
我们有两种方式来实现拦截,一种我们可以通过定义Attribute来实现拦截的功能,在System.Web.Mvc程序集中有一个ActionFilterAttribute抽象类,通过重写这个抽象类的这些虚方法,我们就可以实现对特定的执行过程进行拦截。
另一种方法,我们注意到Controller这个类也实现了IActionFilter这个接口,并且也提供了这四个函数的虚拟方法定义。框架内部,在调用Action方法的时候同时来调用这些拦截方法。具体的可以参考:ControllerActionInvoker这个类的实现,所有的Action的调用都在这个类当中被实现。所以我们只要重写Controller里这四个虚方法,也可完成本Controller面的所有Action的拦截。
在这里,我也找到了国外友人已经实现好的基于角色的MVC权限控制的方案。自定义了两个自定义Attribute,分别为:RequiresAuthenticationAttribute和RequiresRoleAttribute。通过这两个Attribute来可以作用于Class和Method,用标记哪些Controller或Action需要登录后,或者需要拥有哪些角色才能执行。如果用户没有拥有访问当然Controller或Action权限的时候,就会自动被重定向到登录页面去。下面是两个类的定义:
///<summary>
///CheckstheUser'sauthenticationusingFormsAuthentication
///andredirectstotheLoginUrlfortheapplicationonfail
///</summary>
[RequiresAuthentication]
publicclassRequiresAuthenticationAttribute:ActionFilterAttribute
{
publicoverridevoidOnActionExecuting(ActionExecutingContextfilterContext)
{
//redirectifnotauthenticated
if(!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
//usethecurrenturlfortheredirect
stringredirectOnSuccess=filterContext.HttpContext.Request.Url.AbsolutePath;
//sendthemofftotheloginpage
stringredirectUrl=string.Format("?ReturnUrl={0}",redirectOnSuccess);
stringloginUrl=FormsAuthentication.LoginUrl+redirectUrl;
filterContext.HttpContext.Response.Redirect(loginUrl,true);
}
}
}
///<summary>
///CheckstheUser'sroleusingFormsAuthentication
///andthrowsandUnauthorizedAccessExceptionifnotauthorized
///</summary>
publicclassRequiresRoleAttribute:ActionFilterAttribute
{
publicstringRoleToCheckFor{get;set;}
publicoverridevoidOnActionExecuting(ActionExecutingContextfilterContext)
{
//redirectiftheuserisnotauthenticated
if(!String.IsNullOrEmpty(RoleToCheckFor))
{
if(!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
//usethecurrenturlfortheredirect
stringredirectOnSuccess=filterContext.HttpContext.Request.Url.AbsolutePath;
//sendthemofftotheloginpage
stringredirectUrl=string.Format("?ReturnUrl={0}",redirectOnSuccess);
stringloginUrl=FormsAuthentication.LoginUrl+redirectUrl;
filterContext.HttpContext.Response.Redirect(loginUrl,true);
}
else
{
boolisAuthorized=filterContext.HttpContext.User.IsInRole(this.RoleToCheckFor);
if(!isAuthorized)
thrownewUnauthorizedAccessException("Youarenotauthorizedtoviewthispage");
}
}
else
{
thrownewInvalidOperationException("NoRoleSpecified");
}
}
}
如上所介绍的两种方法,我们一样可以定义一个Controller基类,通过拦截来进行权限的控制。但是与定义Attribute相比,手法并不是很好,也不利于通用化。但是就理论上的性能来说,会比Attribute更好。
到目前为止,ASP.NETMVC还没有更新的消息,我想在正式版本的ASP.NETMVC框架,权限控制问题会有一个官方说法。希望到时候会有一种更为灵活和可配置的方案。也许通过控制Url来控制访问权限也是一种可行的方案,会不会集成到RouteTable里面呢?让我们试目以待吧。
上一篇:
广告:
相关文章推荐
- ASP.NET MVC使用Filter实现页面验证与授权
- ASP.NET MVC :MVC页面验证与授权
- ASP.NET MVC :MVC页面验证与授权
- ASP.NET MVC 学习5、登陆页面改为SSO验证
- ASP.NET MVC 随想录——探索ASP.NET Identity 身份验证和基于角色的授权,中级篇
- asp.net mvc利用Json验证数据和导向页面,解决重复提交问题
- ASP.NET MVC 随想录——探索ASP.NET Identity 身份验证和基于角色的授权,中级篇
- ASP.NET MVC 随想录——探索ASP.NET Identity 身份验证和基于角色的授权,中级篇
- ASP.NET MVC 3 RC ValidateInput(false)页面验证失效的解决方案
- ASP.NET MVC 随想录——探索ASP.NET Identity 身份验证和基于角色的授权,中级篇
- Asp.net中Web.config 页面访问按角色授权配置
- ASP.NET MVC 入门8、ModelState与数据验证
- IOS 内付 asp.net mvc 服务器端验证
- Asp.net页面中调用soapheader进行验证的操作步骤
- Asp.net页面中调用soapheader进行验证的操作步骤
- Asp.Net MVC Views页面不包含“GetEnumerator”的公共定义
- 验证一个ASP.NET应用程序和页面的生命周期的实现代码
- ASP.NET MVC Unobtrusive JavaScript 实现 onfocusout 验证, onfocusin 清除错误(转)
- Asp.Net MVC杂谈之:—步步打造表单验证框架(2)