顶部左侧内容
百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 在线教程 > 正文

ASP.NET MVC知识盘点:验证、授权与安全

gosiye 2024-08-30 16:00 7 浏览 0 评论

1 验证

一般采用表单验证完成登陆验证,建议结合SSL使用。为限制控制器只能执行HTTPS,使用RequireHttpsAttribute

2 授权

对账户的权限的控制可以通过在控制器或控制器操作上加AuthorizeAttribute 属性。

扩展授权过滤器

扩展授权过滤器可以定义继承自AuthorizeAttribute的类,也可以定义同时继承自FilterAttribute, IAuthorizationFilter接口的类。

扩展AuthorizeAttribute

 [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(0));
 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 = 1,
 Vip = 2,
 Guest = 3
	}

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注入攻击。

相关推荐

全球最大的H5网站模板库(h5页面模板下载)

当今社会,互联网迅猛发展,在网络营销中,客户往往通过企业的网站建设留下对该企业的第一印象,一个优秀的企业网站已成为企业发展的重要纽带,嗨创H5,拥有国内外一流的技术团队,潜心专研网站建设6年,是全球最...

wordpress集团公司网站模板:XSgr(wordpress建站公司)

小兽wordpress推出一款高端集团公司主题,打造高品质官网。高端是一种态度和坚持,因为我坚信贴合产品及品牌理念的高端深度定制才能最大化地呈现企业的务实严谨与产品的专业品质相比,某种程度上讲–...

私心推荐,小编酷爱的五款高逼格网站模板

建站宝盒的网站模板上千套之多,各有各的风格色彩,但是,弱水三千,小编我却只取一瓢饮,在这上千套模板之中,小编酷爱的网站模板有五套,让小编私心推荐一下吧!1、茶叶贸易公司网站模板小编对这款网站模板可是一...

「书讯」政府网站用户行为研究与应用

《政府网站用户行为研究与应用》作者:刘合翔著出版日期:2018年6月开本:16开出版社:经济管理出版社小编推荐《政府网站用户行为研究与应用》的主题是关于政府网站用户行为的特征规律及其在政府网站优...

免费服务器-搭建模板网站的操作流程(图文版)

之前发文《创业者的官网:如何搭建免费云服务器及操作面板(图文版)》,因为做了视频才发现,创业者对视频的需求,远远低于对图文解说的需求。因此,补充图文教程,不清楚的看官们,可以直接看视频版本进行细部学...

快收藏这些高逼格H5网站模板吧,不绕弯子直接下载

上面这些响应式H5网站是不是很炫酷,比起那些“在线一键生成”是不是好太多了?关键是,那些一键制作都不会开放源码给你,自定义性也很局限。不过说到底还是难看。今天笔者推荐大家一个模板网站,全都是高质量的响...

如何开发网站建设管理系统模板(如何开发网站建设管理系统模板图片)

根据用户网站需求文档设计美工图,并设计数据库结构,让网站开发人员可以更多地关注前台美工,先对照美工图,编写静态HTML页面,按网站建设管理系统模板语法,修改编写好的静态HTML页面,运行。不再需要对...

C语言的数据类型介绍(c语言的数据类型介绍是什么)

在计算机系统中,数据是放在内存中的,数字、文字、符号、图形、音频、视频等数据都是以二进制形式存储在内存中的,它们并没有本质上的区别,那么0001000该理解为数字8呢,还是图像中某个像素的颜色...

C 语言格式化输出函数中常用的格式符号

在之前介绍输入输出函数的文章中,有提到格式化输入输出函数都有包含一种特殊的符号——格式符号。那篇文章中关于格式符号也只是一笔带过,没有进行深入挖掘。本篇文章主要对输出函数(printf)中的一些常用格...

C#中的类型转换(c#数据转换类)

计算机存储的基本单位:字节我们知道一个字节(Byte)有8个比特(bit)构成,比特是存储的最小单位,表示0和1,但为什么计算机存储的基本单位是字节,而不是比特呢?假设我们要存储数字3(二进制:11...

Java8中String内存空间占用分析(电脑里下载的文件怎样删除才不会占用内存空间)

1.前言分析之前,简单回顾一下对象的内存分布。在HotSpot虚拟机中,对象在堆内存中的存储布局可以划分为三部分:对象头、实例数据和对齐填充。对象头包含两部分内容:MarkWord和类型指针。实例数据...

「每日C语言」数据类型大小和取值范围

对于c语言来说,数据类型是一个很重要的概念和知识点,它涉及到的是内存的空间,这在和硬件交互的时候是非常重要的。K&R给出了7个数据类型相关的关键字,分别是:int、long、short、uns...

【c语言学习笔记】数据类型(c语言里面的数据类型)

c语言学习笔记,欢迎大家能在评论区提出我学习错误的地方方便我进行改正~在计算机中,计算机用二进制来储存数据,在c语言中有许多的数据类型用来存储数据,当然不同的数据类型所用的内存占用也不一样,下面就来用...

关于MySQL varchar类型最大值,原来一直都理解错了

我是架构精进之路,点击上方“关注”,坚持每天为你分享技术干货,私信我回复“01”,送你一份程序员成长进阶大礼包。写在前面关于MySQLvarchar字段类型的最大值计算,也许我们一直都理解错误了,...

C语言数据类型的转换(c语言数据类型的转换方式)

类型转换在C语言程序中,经常需要对不同类型的数据进行运算,为了解决数据类型不一致的问题,需要对数据的类型进行转换。例如一个浮点数和一个整数相加,必须先将两个数转换成同一类型。C语言程序中的类型...

取消回复欢迎 发表评论: