AOP有的翻译“面向切面编程”,有的是“面向方面编程”。其实名字不重要,思想才是核心,mvc的Filter让我们很

方便达到这种面向方面编程,就是在现有代码的基础上注入外部代码,也就是所谓的面向方面编程,比如身份

验证。

下面通过一个具体的例子来体验一下MVC的AOP。

1、定义一AuthenAdminAttribute特性类

public class AuthenAdminAttribute : FilterAttribute, IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
//这个方法是在Action执行之前调用
var user = filterContext.HttpContext.Session["AdminUser"];
if (user == null)
{
//filterContext.HttpContext.Response.Redirect("/Account/Logon");
var Url = new UrlHelper(filterContext.RequestContext);
var url = Url.Action("Logon", "Account", new { area=""});
filterContext.Result = new RedirectResult(url);
}
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
//这个方法是在Action执行之后调用
}
}

是否登录是通过Session键值为AdminUser的值是否为null判断,如果为null也就是还没有登录或者过期了,就跳

转到登录页面,即"/Account/Logon"。

注意:上面OnAuthentication是在最开始被调用的,也在ActionFilter方法之前。而OnAuthenticationChallenge

方法是在Action执行之后,返回视图之前被调用。所以要把登录验证写在方法OnAuthentication中。而且在里面

我们用到了设置filterContext.Result = new RedirectResult(url);而不是跳转的形式,很关键的。MVC在执行

Filter时,如果我们手动用一个ActionResult对象指定了其Context对象的Result属性的值,那么这个这个

ActionResult将作为这个请求的结果输出,并且在这次请求管道中剩下的步骤将不再继续执行。反之如果没有

设置filterContext.Result的值,它会继续执行接下来的步骤,甚至是Action方法,就算我们设置了跳转。

2、定义登录Controller

public class ManageController : Controller
{ public ActionResult Logon()
{
return View();
}
[HttpPost]
public ActionResult Logon(string username,string password)
{
if (username == "admin" && password == "admin")
{
Session["AdminUser"] = username;
return RedirectToAction("Index",
"Order", new { area = "Admin" });
}
else
ViewBag.Error = "用户名或密码不正确!";
return View();
} public ActionResult LogOff()
{
if (Session["AdminUser"] != null)
{
Session["AdminUser"] = null;
}
return RedirectToAction("Logon");
}
}

Action名为Logon的方法就是里面就是登录相关逻辑,这里的逻辑我为了简单化,就直接把用户名和密码固定写

死了。当然实际过程中你可以根据你自己的需要,比如结合数据库表记录来判断用户名密码是否合法,如果合

法就相应的信息存在Session里面,当然你也可以存在Cookie里。

注意:这里登录成功之后的存Session的key一定要和上面第一步的AuthenAdminAttribute用到的key一致。

3、设置需要登录判断的Controller或者Action

最后就是根据你的需要,看哪些Controller或者Action需要登录才能访问,只需要在前面加上我们在上面定义好

的特性类就可以了。

[AuthenAdmin]
public class CategoryController : Controller
{
public ActionResult Index()
{
//此处省略具体逻辑代码
return View();
}
}

上面是对整个Controller都要登录验证,就是这个Controller的所有Action必须要登录才能访问。那如果要针对单

独的一个Action控制,其它不做要求呢?这也很好办。代码这样写就可以了。

public class CategoryController : Controller
{
public ActionResult Index()
{
//此处省略具体逻辑代码
return View();
}
[AuthenAdmin]
public ActinResult List()
{
//此处省略具体逻辑代码
return View();
}
}

这样就是只有List这个Action需要登录,Index就不用登录就能访问。

最后,说一下第一步为什么我要自己实现IAuthenticationFilter接口,而不直接继承AuthorizeAttribute,比如这

样写

public class CustomAuthAttribute : AuthorizeAttribute {
private bool localAllowed; public CustomAuthAttribute(bool allowedParam) {
localAllowed = allowedParam;
} protected override bool AuthorizeCore(HttpContextBase httpContext) {
var user = httpContext.Session["AdminUser"];
return user != null
}
}

可以看到AuthorizeAttribute核心方法是AuthorizeCore返回值是一个bool类型,也就是只能判断是否登录过了,

这种情况如果你的系统采用Form验证这个,确实是一个简单可行的方案。如果要涉及到更加细微的权限控制或

者要把登录信息存储到Session或者其实地方就不太好办了,因为ASP.NET的Form验证是基于Cookie的。所以

我一般建议自己实现接口IAuthenticationFilter,这样让我们的系统更加灵活,更加容易扩展和控制。

这样最后来看我们的业务逻辑代码不会有身份验证相关的代码,登录验证和业务逻辑代码完全隔离开了,业务逻

辑代码变得简洁了许多,这就是我理解的:你只需要针对一方面编程,也就是AOP提倡的面向方面编程。AOP

技术让我们的软件模块之间的耦合性降低,大大的提高的我们软件的可维护性和可复用性,AOP你值得拥有。

AOP实践--利用MVC5 Filter实现登录状态判断的更多相关文章

  1. [技术博客] 利用SharedPreferences来实现登录状态的记忆功能

    [技术博客] 利用SharedPreferences来实现登录状态的记忆功能 一.SharedPreferences简介 SharedPreferences是Android平台上一个轻量级的存储辅助类 ...

  2. SpringBoot29 登录逻辑、登录状态判断

    1 知识点扫盲 浏览器和服务器之间时通过session来确定连接状态的,浏览器第一次请求时服务端会自动生成一个session,并将这个sessionId传回给浏览器,浏览器将这个sessionId存放 ...

  3. C# MVC 用户登录状态判断 【C#】list 去重(转载) js 日期格式转换(转载) C#日期转换(转载) Nullable<System.DateTime>日期格式转换 (转载) Asp.Net MVC中Action跳转(转载)

    C# MVC 用户登录状态判断   来源:https://www.cnblogs.com/cherryzhou/p/4978342.html 在Filters文件夹下添加一个类Authenticati ...

  4. filter 实现登录状态控制

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 网站需要做用户登录鉴权控制,没有登录的话,不能访问网站,提示需要登录. 实现方式: 使 ...

  5. vue用户登录状态判断

    之前项目中用来判断是否登录我写了多种方案,但是最终只有一个方案是比较好的,这篇博客就是分享该方案; 先说基本要求: 项目中的登录状态是依据服务器里的状态来作为判断依据; 每一个需要登录后才能操作的接口 ...

  6. C# MVC 用户登录状态判断

    来源:https://www.cnblogs.com/cherryzhou/p/4978342.html 在Filters文件夹下添加一个类AuthenticationAttribute ,代码如下: ...

  7. Struts2重新学习之自定义拦截器(判断用户是否是登录状态)

    拦截器 一:1:概念:Interceptor拦截器类似于我们学习过的过滤器,是可以再action执行前后执行的代码.是web开发时,常用的技术.比如,权限控制,日志记录. 2:多个拦截器Interce ...

  8. App保持登录状态的常用方法(转)

    我们在使用App时,一次登录后App如果不主动退出登录或者清除数据,App会在很长一段时间内保持登录状态,或者让用户感觉到登录一次就不用每次都输入用户密码才能进行登录.银行.金融涉及到支付类的App一 ...

  9. App保持登录状态的常用方法

    我们在使用App时,一次登录后App如果不主动退出登录或者清除数据,App会在很长一段时间内保持登录状态,或者让用户感觉到登录一次就不用每次都输入用户密码才能进行登录.银行.金融涉及到支付类的App一 ...

随机推荐

  1. javax.validation.ValidationException: Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.

    项目依赖 <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifa ...

  2. day 7-9 IO模型

    一,同步和异步,阻塞和非阻塞 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就 ...

  3. java学习之—递归

    /** * 递归 * Create by Administrator * 2018/6/20 0020 * 上午 9:41 **/ public class TriangleApp { static ...

  4. Socket构造但不连接

    Socket socket = new Socket(); SocketAddress address = new InetSocketAddress("localhost",80 ...

  5. Windows开启WMI时一些总结

    通过远程的方式连接WMI获取计算机信息时,可能会出现远程主机拒绝访问,这时就要通过下面的方式来开启当前计算机的WMI服务,下面以Win7和Win10为例来进行相关的说明,通过一步步排查去连接远程服务. ...

  6. shell中的>,2>&1,&>file 解析记录

    0  表示标准输入1  表示标准输出2  表示标准错误输出>  默认为标准输出重定向,与 1> 相同2>&1  意思是把 标准错误输出 重定向到 标准输出.&> ...

  7. 根据request获取请求客户端的外网ip

    //根据request获取外网ip private static String getRemoteIp(HttpServletRequest request) { //x-forwarded-for: ...

  8. POJ 2823 滑动窗口 单调队列

    https://vjudge.net/problem/POJ-2823 中文:https://loj.ac/problem/10175 题目 给一个长度为 $N$ 的数组,一个长为 $K$ 的滑动窗体 ...

  9. 为何CPU散片这么便宜?盒装CPU值得买吗

    当玩家选择装一台PC电脑的时候,他会有个怎样的思考过程?第一个要决定的通常是选什么样的处理器,因为处理器的选择可以决定整套平台的预算及性能水平,想玩游戏的话现在4核8线程处理器是入门标准了,高点的则会 ...

  10. .resx文件与.cs文件的自动匹配

    图中myCommands.Resx是<DependentUpon> myCommands.cs文件的. 如何为其他的.cs文件添加类似的资源文件呢? 其实挺简单, 添加与.cs文件同名的资 ...