ASP.NET MVC自定义AuthorizeAttribute篇知识点讲解—登录限制
1.前言
a.微软对ASP.NET的开发从WebForm到MVC的转变,已经正式过去5,6个年头,现在WebForm和MVC也都越来越完善,小小算来我也已经工作了将近三年,从大学的时候学习ASP.NET WebForm,感觉这就是我们以后吃饭的技术,所以当时可劲的学习拖各种控件,学习做各种各样的小项目,但是没想到的是,从大学最后一学期参加实习开始到现在也就一直没有机会接触ASP.NET WebForm,基本也都是在用MVC开发。我并不是说MVC就比WebForm开发好或者什么的,我只是觉得他们都是工具,只要我们使用任何一种工具能够顺手,能给我们带来更快速的开发和收获,我们就可以去使用它。
b.那么MVC也同时给我们带来了不一样的开发体验,它增加了很多的开发技巧和技术,比如:路由机制(Web Form也已加入),Razor引擎,特性(Attribute)等,随着Visual Studio2015的发布,ASP.NET MVC6的跨平台也已经来到,那么说了这么多,我们今天主要的还是简单说一下MVC的特性,我将这些经常用到的技术都给整理起来,等到我们后面有机会用到的时候直接将其拿出来使用即可。
c.源码(Git)地址:https://github.com/kencery/Common/blob/master/KenceryCommonMethod/AuthorizeAttribute/LoginAttribute.cs
2.AuthorizeAttribute登录特性解释
a.在项目开发中,通常我们都会涉及到用户登录才能访问的网页,比如购物网站,我们浏览商品,添加购物车(以前开发的时候在这里就需要登录用户,但是现在有了缓存的实现,这里可以将商品加入缓存,等到结账的时候在登录)选择结账的时候需要登录,那么这时候我们需要跳转到登录页面登录,登录之后还可以回到记录下来的原始的页面,那么这之后我们有好几种方法可以实现这种效果,简单举例:
(1):第一种:登录模块不管怎么样都是统一的,就是在每个需要登录的方法里面判断用户是否登录,如果没有登录,则跳转登录,这种的缺点是工作量大,代码冗余。
(2):第二种:使用MVC的特性,定义类继承IAuthorizationFilter,重写OnAuthorization方法即可实现。此方法工作量少,代码不冗余,如果需要登录我们只需要给Controller或者Action给上标签即可。
b.任何能够使用特性的判断都可以按照下面的思路来实现,例如(登录判断,权限判断,请求判断,去除空格,读取返回路径)等等,在项目中又遇到这些方方面面需要在请求发起之前或者请求发起之后访问的,都可以实现特性去实现。
c.下面是我简单整理的的a中说的这种需要的特性实现,代码示例如下,请查看:
3.代码示例
a.下面我简单说一下这个实现的思路,如果大家有什么意见可以在底下留言,纯属于整理,没多少技术含量,请大家见谅,如果代码不能实现你们的需求,请按照你们的需求更改即可实现。
(1).首先定义类继承自FilterAttribute, IAuthorizationFilter,会让你实现重写OnAuthorization方法。
(2).从web.Config中存放三个常量(登录地址,登录Session或Cookie键,Session或者Cookie登录的判断),在构造函数中读取Web.Config中的信息,实现构造函数。
(3).重写OnAuthorization方法,判断是Cookie或者Session记录用户登录信息,然后判断Session或者Cookie是否为空,如果为空,则登录至指定的地址,否则退出即可。
(4).使用,如果Controller或者Action需要判断是否登录,则打上特性[Login],否则不需要,如果在某一个Controller中,大部分方法需要,只有一两个不需要,在Controller中打上特性[Login],在不需要的方法上打上特性[AllowAnonymous]即可实现。
b.上面说了这么多,基本都是一些思路,实现代码示例如下,请查看:
// 源文件头信息:
// <copyright file="LoginAttribute.cs">
// Copyright(c)2014-2034 Kencery.All rights reserved.
// 个人博客:http://www.cnblogs.com/hanyinglong
// 创建人:韩迎龙(kencery)
// 创建时间:2015-8-7
// </copyright> using System;
using System.Web;
using System.Web.Mvc;
using System.Web.UI.WebControls; namespace KenceryCommonMethod
{
/// <summary>
/// 添加此特性的功能是:需要用户登录才能够浏览网页,如果不需要用户登录,则可以使用AllowAnonymousAttribute属性
/// 使用:给ASP.NET MVC中的控制器类名或者Action方法上面打上[Login]标签
/// 如果不需要验证用户是否登录就可以浏览,则给ASP.NET MVC中的控制器类名或者Action方法上面打上[AllowAnonymous]标签
/// </summary>
/// <auther>
/// <name>Kencery</name>
/// <date>2015-8-7</date>
/// </auther>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class LoginAttribute : FilterAttribute, IAuthorizationFilter
{
/// <summary>
/// 该值表示登录地址:默认路径为user/login,在Web.Config中设置
/// </summary>
private string _authUrl = string.Empty; public string AuthUrl
{
get
{
return _authUrl.Trim();
}
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException("AuthUrl为空,验证用户登录信息的用户登录地址不能为空");
}
_authUrl = value.Trim();
}
} /// <summary>
/// 该值表示yoghurt登录保存登录信息的键名,默认user,在web.Config中设置
/// </summary>
private string _authSaveKey = string.Empty; public string AuthSaveKey
{
get { return _authSaveKey.Trim(); }
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException("AuthSaveKey为空,验证用户登录的时候保存的登录键信息不能为空");
}
_authSaveKey = value.Trim();
}
} /// <summary>
/// 该值表示用户登录保存登录信息的类型,默认Session,在web.Config中设置
/// </summary>
private string _authSaveType = string.Empty; public string AuthSaveType
{
get { return _authSaveType.Trim().ToUpper(); }
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException("AuthSaveType为空,验证用户登录的时候未保存键信息类型,类型不能为空");
}
_authSaveType = value.Trim().ToUpper();
}
} /// <summary>
/// 默认构造函数
/// </summary>
public LoginAttribute()
{
const string authUrl = "/User/Index"; //登录页面路径,从Web.Config中读取
const string saveKey = "user"; //验证(登录存放用户信息),从Web.Config中读取
const string saveType = "Session"; //存放类型判断(Session或者Cookie存放),,从Web.Config中读取
_authUrl = string.IsNullOrEmpty(authUrl) ? "/User/Index" : authUrl; } /// <summary>
/// 构造函数重载
/// </summary>
/// <param name="authUrl"></param>
public LoginAttribute(string authUrl) : this()
{
_authUrl = authUrl;
} /// <summary>
/// 构造函数重载
/// </summary>
/// <param name="authUrl"></param>
/// <param name="saveKey"></param>
public LoginAttribute(string authUrl, string saveKey) : this(authUrl)
{
_authSaveKey = saveKey;
_authSaveType = "Session";
} /// <summary>
/// 构造函数重载
/// </summary>
/// <param name="authUrl"></param>
/// <param name="saveKey"></param>
/// <param name="saveType"></param>
public LoginAttribute(string authUrl, string saveKey, string saveType) : this(authUrl, saveKey)
{
_authSaveType = saveType;
} public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext == null)
{
throw new Exception("此特性只试用于Web应用程序试用");
}
var flAd = filterContext.ActionDescriptor;
var url = string.Format("{0}?Ref=/{1}/{2}", _authUrl, flAd.ControllerDescriptor.ControllerName,
flAd.ActionName);
switch (AuthSaveType)
{
case "SESSION":
if (filterContext.HttpContext.Session == null)
{
throw new Exception("服务器Session不可用");
}
if (!filterContext.ActionDescriptor.IsDefined(typeof (AllowAnonymousAttribute), true) &&
!filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(
typeof (AllowAnonymousAttribute), true))
{
if (filterContext.HttpContext.Session[_authSaveKey] == null)
{
filterContext.Result = new RedirectResult(url);
}
}
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(url);
}
}
break;
default:
throw new ArgumentNullException("用户保存登录信息的方法不能为空,只能为Cookie和Session,请您检查");
}
}
}
}
ASP.NET MVC自定义AuthorizeAttribute篇知识点讲解—登录限制的更多相关文章
- Asp.net Mvc 自定义Session (二)
在 Asp.net Mvc 自定义Session (一)中我们把数据缓存工具类写好了,今天在我们在这篇把 剩下的自定义Session写完 首先还请大家跟着我的思路一步步的来实现,既然我们要自定义Ses ...
- asp.net mvc 自定义pager封装与优化
asp.net mvc 自定义pager封装与优化 Intro 之前做了一个通用的分页组件,但是有些不足,从翻页事件和分页样式都融合在后台代码中,到翻页事件可以自定义,再到翻页和样式都和代码分离, 自 ...
- ASP.NET MVC 自定义路由中几个需要注意的小细节
本文主要记录在ASP.NET MVC自定义路由时,一个需要注意的参数设置小细节. 举例来说,就是在访问 http://localhost/Home/About/arg1/arg2/arg3 这样的自定 ...
- Asp.net mvc 自定义全局的错误事件HandleErrorAttribute无效
Asp.net mvc 自定义全局的错误事件HandleErrorAttribute,结果无效, 原因: 1.没有在RegisterGlobalFilters 里面添加或者你要的位置添加. 2.你把这 ...
- MVC自定义AuthorizeAttribute实现权限管理
[转]MVC自定义AuthorizeAttribute实现权限管理 原文载自:小飞的DD http://www.cnblogs.com/feiDD/articles/2844447.html 网站的权 ...
- ASP.NET MVC自定义验证Authorize Attribute(包含cookie helper)
前几天Insus.NET有在数据库实现过对某一字段进行加密码与解密<使用EncryptByPassPhrase和DecryptByPassPhrase对MS SQLServer某一字段时行加密和 ...
- ASP.NET MVC 自定义Razor视图WorkContext
概述 1.在ASP.NET MVC项目开发的过程中,我们经常需要在cshtml的视图层输出一些公用信息 比如:页面Title.服务器日期时间.页面关键字.关键字描述.系统版本号.资源版本号等 2.普通 ...
- asp.net MVC 自定义模型绑定 从客户端中检测到有潜在危险的 Request.QueryString 值
asp.net mvc 自定义模型绑定 有潜在的Requset.Form 自定义了一个模型绑定器.前端会传过来一些敏感字符.调用bindContext. valueProvider.GetValue( ...
- asp.net MVC之AuthorizeAttribute浅析
AuthorizeAttribute是asp.net MVC的几大过滤器之一,俗称认证和授权过滤器,也就是判断登录与否,授权与否.当为某一个Controller或Action附加该特性时,没有登录或授 ...
随机推荐
- 【转载】uclibc和glibc的差别
转载自:http://blog.163.com/huangnan0727@126/blog/static/30626184201042022011225/ CC的标准库,就是glibc这个库,里面有G ...
- python进阶学习笔记(四)--多线程thread
在使用多线程之前,我们首页要理解什么是进程和线程. 什么是进程? 计算机程序只不过是磁盘中可执行的,二进制(或其它类型)的数据.它们只有在被读取到内存中,被操作系统调用的时候才开始它们的生命期.进程( ...
- Ladda – 把加载提示效果集成到按钮中,提升用户体验
Ladda 是一组集成了加载提示的按钮,以弥合行动和反馈之间的时间间隔,提供更好的功能使用体验.主要用于在用户点击提交之后,向用户提供即时的反馈,让他们知道浏览器正在处用户提交的任务. 您可能感兴趣的 ...
- [python]爬代理ip v2.0(未完待续)
爬代理ip 所有的代码都放到了我的github上面, HTTP代理常识 HTTP代理按匿名度可分为透明代理.匿名代理和高度匿名代理. 特别感谢:勤奋的小孩 在评论中指出我文章中的错误. REMOTE_ ...
- 浅谈Mysql的MyIsam存储类型
前两年的工作,用NoSql多一些!最近进入了传统的软件开发公司,开始使用Mysql多了!不过对于我这种ABC级别的人来说,还是好好看书吧! 我常常觉得,如果我们不是明白原理,而只是知道一些概念,或者说 ...
- 文本溢出text-overflow
文本溢出text-overflow 问题:有一个新闻标题,标题宽度为200px,文字为宋体,加粗,文字大小为16px,颜色为黑色,行高为25px,要求单行显示,并且超出时显示“…”,请按要求完成效果. ...
- 写出优美代码的两个方式:一步到位VS迭代优化
最近把手头这个安卓APP的所有事务性方法都写完了,有了以下体会,新手体会,老鸟轻拍 想写成优美代码的人一般都会有这样的想法: 一定要在写每一句代码,写每一个方法,构造每一个类的时候,都要记得优化: ...
- Scrum 项目 6.0
-------------------------6.0------------------------------------ sprint演示 1.坚持所有的sprint都结束于演示. 团队的成果 ...
- 第一次Sprint总结
回顾流程 这次我们做(done)的是设计用户登录界面.注册界面.查询功能.链接数据库等,我们成功地把todo变成了done,首先不管我们结果如何,不管我们的付出是否与收获成正比,但我们做到了 ...
- 2014 Asia AnShan Regional Contest --- HDU 5073 Galaxy
Galaxy Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5073 Mean: 在一条数轴上,有n颗卫星,现在你可以改变k颗 ...