.Net Mvc5Filter与权限认证扩展
WebForm
在做WebForm的时候,如果我们要实现某页面登陆后才能访问,这个非常容易实现
public partial class IndexForm : Page
{
protected void Page_Load(object sender, EventArgs e)
{
//检查是否登录(session/cookie),失败跳转登录,成功继续访问
}
}
但是实际工作中,不会只有一个页面需要权限检查,当我们面对多个页面的时候,该如何处理呢?这个时候一般会采取下列这种处理方式:
public partial class IndexForm : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
//do something
}
} public partial class BasePage : Page
{
/// <summary>
/// Pre_Init页面加载最早发生的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void Pre_Init(object sender, EventArgs e)
{
//检查用户登录(session/cookie)成功就继续,失败就跳转到登陆页
//需要检查的页面就继承BasePage
if (true)
{
//继续访问
}
else
{
//跳转登录
}
}
}
流程图

这是一个通过继承方式的解决方法,当我们页面需要权限验证的时候,只需要继承我们的带有验证方法的BasePage,而不需要验证的页面,只需要继承BasePageWithoutAuth,但是,当功能比较复杂的时候,用户登录还能用BasePage处理, 而异常处理,日志处理,缓存处理等这些可能这种方式就解决不了, 就必须在每个页面内处理完成,这就导致了很多页面重复出现了相同功能的代码
filter与AOP
AOP(Aspect Oriented Programming)面向切面编程:在不破坏类型封装的前提下,额外的添加功能.
filter即过滤器,是AOP思想在mvc中的一种具体实现,对于webform中出现的上述问题,在mvc框架中能够用filter以AOP的方式解决,
过滤器是在执行某一个方法之前,先去执行其他的某些操作,当执行完成后再确定后续动作。相当于在我们具体方法的业务逻辑之外又额外的添加了一些功能,例如权限认证,异常处理,日志记录等,我们可以把我们的业务逻辑与这些功能组合起来,而又不会被影响
filter之权限认证自定义扩展
上面说到过滤器filter可以实现请求方法前做权限校验、登录校验等,比如说只有登录的用户才可以访问这个方法,需要进行Session的校验。如果有很多的控制器中的方法都需要校验session,后期维护也是非常的不方便的,所以只需要将这种校验放在Filter中就可以了。
MVC框架自带有默认权限认证的特性[Authorize]
namespace System.Web.Mvc
{
//
// 摘要:
// 指定对控制器或操作方法的访问只限于满足授权要求的用户。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
{
//
// 摘要:
// 初始化 System.Web.Mvc.AuthorizeAttribute 类的新实例。
public AuthorizeAttribute(); //
// 摘要:
// 获取或设置有权访问控制器或操作方法的用户角色。
//
// 返回结果:
// 有权访问控制器或操作方法的用户角色。
public string Roles { get; set; }
//
// 摘要:
// 获取此特性的唯一标识符。
//
// 返回结果:
// 此特性的唯一标识符。
public override object TypeId { get; }
//
// 摘要:
// 获取或设置有权访问控制器或操作方法的用户。
//
// 返回结果:
// 有权访问控制器或操作方法的用户。
public string Users { get; set; } //
// 摘要:
// 在过程请求授权时调用。
//
// 参数:
// filterContext:
// 筛选器上下文,它封装有关使用 System.Web.Mvc.AuthorizeAttribute 的信息。
//
// 异常:
// T:System.ArgumentNullException:
// filterContext 参数为 null。
public virtual void OnAuthorization(AuthorizationContext filterContext);
//
// 摘要:
// 重写时,提供一个入口点用于进行自定义授权检查。
//
// 参数:
// httpContext:
// HTTP 上下文,它封装有关单个 HTTP 请求的所有 HTTP 特定的信息。
//
// 返回结果:
// 如果用户已经过授权,则为 true;否则为 false。
//
// 异常:
// T:System.ArgumentNullException:
// httpContext 参数为 null。
protected virtual bool AuthorizeCore(HttpContextBase httpContext);
//
// 摘要:
// 处理未能授权的 HTTP 请求。
//
// 参数:
// filterContext:
// 封装有关使用 System.Web.Mvc.AuthorizeAttribute 的信息。filterContext 对象包括控制器、HTTP 上下文、请求上下文、操作结果和路由数据。
protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext);
//
// 摘要:
// 在缓存模块请求授权时调用。
//
// 参数:
// httpContext:
// HTTP 上下文,它封装有关单个 HTTP 请求的所有 HTTP 特定的信息。
//
// 返回结果:
// 对验证状态的引用。
//
// 异常:
// T:System.ArgumentNullException:
// httpContext 参数为 null。
protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext);
}
}
AuthorizeAttribute
但是框架的自带东西有时候很难满足我们的需要,在此基础上我们可以继承AuthorizeAttribute,然后复写扩展(一般而言,带有virtual关键字的,都可以复写)
例如检查请求地址是否带有Account和Password的参数,值分别为Admin和123456,如果满足,则可以继续访问,否则返回指定的路径
public class CustomerAuthorizeAttribute: AuthorizeAttribute
{
private string LoginUrl = string.Empty;
public CustomerAuthorizeAttribute()
{
LoginUrl = "/Home/Login";
} public CustomerAuthorizeAttribute(string loginUrl)
{
LoginUrl = loginUrl;
}
/// <summary>
/// 请求进入具体action前,先执行OnAuthorization方法
/// </summary>
/// <param name="filterContext"></param>
public override void OnAuthorization(AuthorizationContext filterContext)
{
//base.OnAuthorization(filterContext);
//filterContext.HttpContext 能拿到HttpContext,意味着我们能拿到一切请求的信息
if (filterContext.HttpContext.Request.QueryString["Account"]=="Admin"
&& filterContext.HttpContext.Request.QueryString["Password"] == "")
{
return;
}
else
{
filterContext.Result = new RedirectResult(LoginUrl);
}
} }
只需要在需要权限认证的方法上加上[CustomerAuthorizeFilter]特性即可.
这就是AOP的魅力所在,只用加上一个特性,就完成了一个验证权限的功能,而且本身的业务逻辑封装没有一丝的破坏
Filter的三种注册方式
1方法注册
只给一个方法加权限认证的特性,那么就只会有特定的方法才会有权限验证
2类注册
给某个控制器加权限认证的特性,那么该控制器下所有的方法都有权限验证,但是要注意死循环,如果验证失败返回的路径也在该控制器下,那么会再次验证,然后返回再验证,一直重定向,最后重定向次数过多,页面崩溃
[CustomerAuthorize]//类注册
public class HomeController : Controller
{
[CustomerAuthorize("Home/About")]//方法注册
public ActionResult Index()
{
return View();
} public ActionResult About()
{
ViewBag.Message = "Your application description page."; return View();
} public ActionResult Contact()
{
ViewBag.Message = "Your contact page."; return View();
} //此处若是类注册,且为失败返回的路径,则会死循环
public ActionResult Login()
{
ViewBag.Message = "Your Login page."; return View();
}
}
3全局注册
在Global.asax全局配置文件里面,有过滤器的配置文件FilterConfig.cs,在App_Start目录下,如果在这里面注册上述的权限认证特性,则所有的页面都会有权限验证
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomerAuthorizeAttribute());//全局注册
filters.Add(new HandleErrorAttribute());//全局异常处理
}
}
匿名登录
如果我们类注册了权限验证特性,但是在该类下面有几个需要匿名登陆的方法,那么是否意味着需要将这几个方法移到其他的控制器呢?其实不然,我们只需要给这些方法加上AllowAnonymous特性,在上述自定义特性里面先判断时候是否加了该特性即可.这里其实用什么做匿名特性都可以,只是AllowAnonymous是框架自带的一个匿名特性,就直接用了,如果想用自定义的匿名特性,再创建一个特性就可以了,什么都不需要加,只是用于标记.
if (filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute),true))
{
return;
}
出自:博客园-半路独行
原文地址:https://www.cnblogs.com/banluduxing/p/9185182.html
本文出自于http://www.cnblogs.com/banluduxing 转载请注明出处。
代码地址:https://github.com/weiweu/My-space/tree/master/Design/DecoratorPattern
.Net Mvc5Filter与权限认证扩展的更多相关文章
- Codeigniter-实现权限认证
两种方法 钩子函数 集成核心Controller 方法一,钩子函数: 一直没找到CI的权限认证扩展,以前好像找到过一个老外的扩展,不过不怎么好用,现在记不清了,后来仿着jsp firter的方式用CI ...
- thinkphp5的auth权限认证(转自thinkphp官方文档+自己总结)
thinkphp5的auth权限认证(转自thinkphp官方文档+自己总结) 一.总结 一句话总结:相当于就是用其它thinkphp的扩展一样,都是引入扩展,配置扩展,然后使用 引入 配置 使用 基 ...
- auth权限认证详细讲解
auth权限认证详细讲解 一.总结 一句话总结:四表两组关系,一个多对多(权限和用户组之间)(多对多需要3个表),一个一对多(用户和用户组之间) 1.实际上使用Auth是需要4张表的(1.会员表 2. ...
- **[权限控制] 利用CI钩子实现权限认证
http://codeigniter.org.cn/forums/thread-10877-1-1.html 一直没找到CI的权限认证扩展,以前好像找到过一个老外的扩展,不过不怎么好用,现在记不清了, ...
- .Net Core权限认证基于Cookie的认证&授权.Scheme、Policy扩展
在身份认证中,如果某个Action需要权限才能访问,最开始的想法就是,哪个Action需要权限才能访问,我们写个特性标注到上面即可,[TypeFilter(typeof(CustomAuthorize ...
- JWT实现用户权限认证
网上的java基础教程曾教会我们,将用户登录信息存在session(服务器端)中,需要验证的时候拿出来作对比以达到身份 验证的效果.但这种方式暴露的问题也是可想而知的: 1.Seesion:每次认证用 ...
- DRF之权限认证,过滤分页,异常处理
1. 认证Authentication 在配置文件中配置全局默认的认证方案 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_f ...
- Thinkphp基于规则的Auth权限认证类
PS:onethink是基于该权限认证类实现,Auth类作为官方类库,在Library\Think里面. 其实Auth类也是基于角色访问控制RBAC扩展的,具体到节点的权限校验方式还是需要根据业务 ...
- Thinkphp5 Auth权限认证
Thinkphp5 Auth权限认证 一.总结 一句话总结:四表两组关系,一个多对多(权限和用户组之间),一个一对多(用户和用户组之间) 二.Thinkphp5 Auth权限认证 auth类在thin ...
随机推荐
- linux记录每个用户执行的命令
1.在/etc/profile中添加如下代码: #history USER_IP=`>/dev/null| awk '{print $NF}'|sed -e 's/[()]//g'` HISTD ...
- oracle完全删除表空间
步骤一: 删除user drop user ×× cascade 说明: 删除了user,只是删除了该user下的schema objects,是不会删除相应的tablespace的. 步骤二: 删除 ...
- 修改eclipse 代码字体大小以及文档字体大小
1..点击[window]在弹出的窗口中选择[preferences] 2.在弹出窗口中找到依次点击General(常规)——Apprearance(外观)——Colors and Fonts(颜色和 ...
- Linux Tomcat8 访问管理页面 403 Access Denied
http://blog.csdn.net/u012167045/article/details/61624226 1:修改conf/tomcat-users.xml配置文件 2:vi /usr/loc ...
- Spring cloud 两种服务调用方式(Rest + Ribbon) 和 Fegin方式
1:Rest + Ribbon @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } @Auto ...
- VLC接收网络串流缓冲时间的计算 (转)
原帖地址:http://blog.csdn.net/coroutines/article/details/7472743 VLC版本2.0.1 最近研究IP-STB音视频同步问题,发现方案自带的自动S ...
- [ShaderStaff] Vignette Effect
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:GLSL | C 最近在看Cardboard实现,其中关于畸变的着色器代码中有加入 晕影Vignette 效果的实现,固在 ...
- codeforces:Prefix Sums分析和实现
题目大意: 给出一个函数P,P接受一个数组A作为参数,并返回一个新的数组B,且B.length = A.length + 1,B[i] = SUM(A[0], ..., A[i]).有一个无穷数组序列 ...
- myeclipse10安装了activiti插件后创建BPMN 文件时报错,
以上错误需要,下载一个补丁. 补丁地址:http://www.shareyx.com/blog/2 补丁的安装可以参考: http://jingyan.baidu.com/article/dca1fa ...
- Bean标签的常用属性
-----------------siwuxie095 Bean 标签的常用属性 1.id 属性:Bean 的唯一标识名,必须以字母开头,且不能 包含特殊字符 2.class 属性:用来定义类的全限定 ...