ASP.NET MVC编程——验证、授权与安全
1 验证
一般采用表单验证完成登陆验证,建议结合SSL使用。为限制控制器只能执行HTTPS,使用RequireHttpsAttribute
2 授权
对账户的权限的控制可以通过在控制器或控制器操作上加AuthorizeAttribute 属性。
扩展授权过滤器
扩展授权过滤器可以定义继承自AuthorizeAttribute的类,也可以定义同时继承自FilterAttribute, IAuthorizationFilter接口的类。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
{
public AuthorizeAttribute(); // 获取或设置有权访问控制器或操作方法的用户角色
public string Roles { get; set; } //获取此特性的唯一标识符。
public override object TypeId { get; } // 获取或设置有权访问控制器或操作方法的用户。
public string Users { get; set; } //重写时,提供一个入口点用于进行自定义授权检查
// 返回结果: 如果用户已经过授权,则为 true;否则为 false。
// 异常:System.ArgumentNullException:httpContext 参数为 null。
protected virtual bool AuthorizeCore(HttpContextBase httpContext); //处理未能授权的 HTTP 请求。
protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext); //在过程请求授权时调用。
// 异常: System.ArgumentNullException:
//filterContext 参数为 null。
public virtual void OnAuthorization(AuthorizationContext filterContext); // 返回结果: 对验证状态的引用。
// 异常:System.ArgumentNullException:
// httpContext 参数为 null。
protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext);
}
AuthorizeAttribute提供了三个可重新的虚方法AuthorizeCore,HandleUnauthorizedRequest,OnAuthorization,那么在执行授权动作的过程中他们是如何被调用的呢?看下源码的OnAuthorization方法,发现在这个方法中先调用AuthorizeCore,然后调用HandleUnauthorizedRequest被调用了。
public virtual void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
//如果子操作的缓存处于活动状态,那么就抛出异常
if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
{
throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
}
//判断控制器或控制器操作是否允许匿名访问,如果可以就return
bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true); if (skipAuthorization)
{
return;
}
//进行权限验证
if (AuthorizeCore(filterContext.HttpContext))
{
HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge(new TimeSpan());
cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
}
else
{//处理未通过权限验证的情形
HandleUnauthorizedRequest(filterContext);
}
}
当子操作缓存处于活动状态,那么抛出异常。然后检验是否可匿名访问,如果可以匿名访问就不进行验证;
综合以上分析,扩展AuthorizeAttribute要注意:
1)在子类AuthorizeCore中,调用父类的AuthorizeCore方法
base.OnAuthorization(filterContext);
2)在子类的AuthorizeCore方法中验证用户的权限。
3)通过子类的构造函数传入用户的权限值
代码示例如下:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
private UserRole role;
public CustomAuthorizeAttribute(UserRole role)
{
this.role = role;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool ret = false; //获得用户信息(从本地Session或分布式缓存中获取)
var userInfo = ......
if(userInfo==null)
{
//信息为null,一般认为登陆超时或没有登陆
} if(userInfo.Role == UserRole.Org)
{
ret = true;
}
else
{
//提示无权限
} return ret;
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
} if (filterContext.HttpContext.Request.IsAjaxRequest())
{//针对ajax请求进行处理 }
else
{//非aiax进行处理 //跳转到指定页面
string strUrl = ......;
filterContext.Result = new RedirectResult(strUrl);
}
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
}
}
public enum UserRole
{
Org = ,
Vip = ,
Guest =
}
3 安全
总的原则:
所有层或各个子系统各自负责好自己的安全。
任何用户数据和来自其他系统的数据都要经过检验。
在满足需求的情况下,尽量缩小账户的权限。
减少暴露的操作数量和操作参数。
关闭服务器不需要的功能。
4 防范攻击
4.1跨站脚本攻击(XSS)
被动注入:用户的输入含有恶意脚本,而网站又能够不加检验地接受这样的输入,进而保存到数据库中。
主动注入:用户将含有恶意脚本的内容输入到页面文本框中,然后在屏幕上显示出来。
防御方法:
1)使用Razor语法输出的内容已经被编码,可以不做任何其他处理
例如:
<h4>@Model.Field</h4>
Html.ActionLink,Html.Action等方法会将路由参数编码输出
2)大部分的XSS攻击可通过对输入内容进行编码来阻止:Html.Encode,Html.AttributeEncode,Url.Encode
3)对Js进行编码
使用Ajax.JavaScriptStringEncode
4)将AntiXSS库作为默认的编码器(不建议使用,不灵活)
ASP.NET 4.5 集成Anti-XSS Library,可以通过配置来对整个网站的输出进行编码。
<system.web>
<httpRuntime targetFramework="4.5" encoderType="System.Web.Security.AntiXss.AntiXssEncoder,System.Web"/>
</system.web>
4.2跨站请求伪造(CSRF/XSRF)
防御方法:
1)使用Html隐藏域存储用户令牌,令牌可以存储在Session里或者cookie里
2)在视图表单中使用@Html.AntiForgeryToken(),在控制器操作上添加属性[ValidateAntiForgeryToken],注意表单一定要使用@Html.BeginForm生成
实现机制:AntiForgeryToken方法向用户浏览器cookie中写入一个加密的数据,并在表单内插入一个隐藏栏位,每次刷新页面时隐藏栏位的值都不同,每次执行控制器操作前,都会验证隐藏栏位和浏览器cookie中的值是否相同,只有相同才允许执行控制器操作。
使用限制:
- 客户端浏览器不能禁用cookie
- 只对post请求有效
- 若有XSS漏洞,则可轻易获取令牌
- 对Ajax请求不能传递令牌,即对Ajax无效
3)使用幂等的Get请求,仅使用Post请求修改数据(仅仅是一定程度上限制这种攻击而已)
4)使用动作过滤器,验证UrlReferrer
扩展的动作过滤器:
public class CSRFFilter:AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext == null)
{
throw new HttpException("请求无效");
} if (filterContext.HttpContext.Request.UrlReferrer == null)
{
throw new HttpException("请求无效");
} if (filterContext.HttpContext.Request.UrlReferrer.Host != "sit.com")
{
throw new HttpException("来自非法网站");
}
}
}
4.3 cookie盗窃
cookie有两种形式
1)会话cookie:存储在浏览器内存中,浏览器每次请求通过Http头进行传递
2)持久性cookie:存储在硬盘上,同样通过Http头进行传递
二者的区别:会话cookie常在会话结束时失效,而持久性cookie在下一次访问站点时仍然有效。
被窃取的原因:依赖于XSS漏洞,注入一段恶意脚本就能窃取。
防御方法:
1)在web.config对cookie进行设置
<httpCookies httpOnlyCookies="true"/>,httpOnlyCookies指定为true表达仅服务器可以访问,浏览器无法访问
2)在编写代码时为每个cookie单独设置
Response.Cookies["cok"].Value = Guid.NewGuid().ToString();
Response.Cookies["cok"].HttpOnly = true;
4.4重复提交
防御方法:
1)使用bind特性,设置想要绑定的属性来,防止这种攻击。也可以设置不要绑定的字属性,但优先选择设置要绑定的属性。
例:
可以指定多个字段,用逗号分隔
public ActionResult TestViewData([Bind(Include = "Field,Field1,Field1")]ModelF mf)
{
......
}
2)使用UpdateModel或TryUpdateModel
3)使用ViewModel,明确规定View使用的数据模型
4.5开放重定向
防御方法:
使用Url.IsLocalUrl检测是否为本地url
4.6 SQL注入攻击
防御方法:
通过参数注入非法获得或修改网站数据。
使用参数化查询来防止SQL注入攻击。
参考:
1.Jess Chadwick/Todd Snyder/Hrusikesh Panda,徐雷/徐扬
译。ASP.NET MVC4 Web编程
2.Jon Galloway/Phil Haack/Brad Wilson/K. Scott Allen,孙远帅/邹权译 ASP.NET MVC4 高级编程(第四版)
3.黄保翕,ASP.NET MVC4开发指南
4.蒋金楠,ASP.NET MVC4框架揭秘
5.https://www.asp.net/mvc
转载与引用请注明出处。 时间仓促,水平有限,如有不当之处,欢迎指正。
ASP.NET MVC编程——验证、授权与安全的更多相关文章
- 七天学会ASP.NET MVC (四)——用户授权认证问题
小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在第四天的学习中,我们主要了学习如何在MVC中如何实现认证授权等问题,本节主要讲了验证错误时的错误值,客户端验 ...
- 通过扩展改善ASP.NET MVC的验证机制[实现篇]
原文:通过扩展改善ASP.NET MVC的验证机制[实现篇] 在<使用篇>中我们谈到扩展的验证编程方式,并且演示了本解决方案的三大特性:消息提供机制的分离.多语言的支持和多验证规则的支持, ...
- ASP.NET MVC 编程参考
ASP.NET MVC 编程参考 转载请注明出处:http://surfsky.cnblogs.com MVC 参考 http://msdn.microsoft.com/zh-cn/dd40 ...
- 七天学会ASP.NET MVC (四)——用户授权认证问题 【转】
http://www.cnblogs.com/powertoolsteam/p/MVC_four.html 小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在 ...
- ASP.NET MVC Model验证(五)
ASP.NET MVC Model验证(五) 前言 上篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现, 然而在MVC框架中还给我们提供了其它 ...
- ASP.NET MVC Model验证(四)
ASP.NET MVC Model验证(四) 前言 本篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现,前者是Model验证提供程序,而Mod ...
- ASP.NET MVC Model验证(三)
ASP.NET MVC Model验证(三) 前言 上篇中说到在MVC框架中默认的Model验证是在哪里验证的,还讲到DefaultModelBinder类型的内部执行的示意图,让大家可以看到默认的M ...
- ASP.NET MVC Model验证(二)
ASP.NET MVC Model验证(二) 前言 上篇内容演示了一个简单的Model验证示例,然后在文中提及到Model验证在MVC框架中默认所处的位置在哪?本篇就是来解决这个问题的,并且会描述一下 ...
- ASP.NET MVC Model验证(一)
ASP.NET MVC Model验证(一) 前言 前面对于Model绑定部分作了大概的介绍,从这章开始就进入Model验证部分了,这个实际上是一个系列的Model的绑定往往都是伴随着验证的.也会在后 ...
随机推荐
- 使用基于Android网络通信的OkHttp库实现Get和Post方式简单操作服务器JSON格式数据
目录 前言 1 Get方式和Post方式接口说明 2 OkHttp库简单介绍及环境配置 3 具体实现 前言 本文具体实现思路和大部分代码参考自<第一行代码>第2版,作者:郭霖:但是文中讲 ...
- Object方法
1. getClass() 返回此 Object 的运行时类. 2. hashCode() 返回该对象的哈希码值. 3. equals() 指示其他某个对象是否与此对象“相等”. 4. toStrin ...
- 【前端】Vue和Vux开发WebApp日志四、增加命令行参数
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/vue_vux_4.html 项目github地址:https://github.com/shamoyuu/vue- ...
- 利用ffmpeg做视频解码的顺序
这几天在实验室捣鼓着用ffmpeg做视频解码,终于把数据解出来了,虽然还没有做显示部分,不知道解码解得对不对,但料想是不会有什么问题了.回头看看这几天的工作,其间也遇到了不少问题,主要还是对ffmpe ...
- MP4文件格式的解析
MP4文件格式的解析,以及MP4文件的分割算法 mp4应该算是一种比较复杂的媒体格式了,起源于QuickTime.以前研究的时候就花了一番的功夫,尤其是如何把它完美的融入到视频点播应用中,更是费尽了心 ...
- jquery Dialog弹框插件使用
var dialog = new Dialog({ title: '购物车', type: 'url', width: 520, content: "Uplolo.aspx", s ...
- ubuntu14.04安装cuda
1 装系统时候注意,另外14.04要好于12.04,自带了无线驱动 ubuntu14.04安装完不要update 2 安装cuda和cudnn http://blog.csdn.net/l297969 ...
- 简单使用Mysql-Cluster-7.5搭建数据库集群
阅读目录 前言 mysql cluster中的几个概念解释 架构图及说明 下载mysql cluster 安装mysql cluster之前 安装配置管理节点 安装配置数据和mysql节点 测试 启动 ...
- 如何解决 touchstart 事件与 click 事件的冲突
一 · 业务场景的描述 在对已完成的PC站点进行移动端适配时,我们想要站点在移动设备上有更快的响应速度,以带给用户更好的体验,此时,我们应该使用移动设备专用的事件系统,例如,使用 touchstart ...
- 【洛谷1026】【NOIP2001】统计单词个数
题面 题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包 ...