ASP.Net MVC 5 高级编程 第7章 成员资格、受权和安全性

第7章 成员资格、受权和安全性

7.1 安全性

ASP.NET MVC 提供了许多内置的保护机制(默认利用 HTML 辅助方法和Razor 语法进行 HTML编码以及请求验证等功能特性,以及经过基架构建的控制器白名单表单元素来防止重复提交攻击)web

永远不要相信用户提交的任何数据。数据库

实际的例子浏览器

  • 每次渲染用户提交的数据的时候对其进行编码。
  • 考虑好网站哪些部分容许用户匿名访问,哪些部分须要认证访问。
  • 不要试图本身净化用户的HTML 输入,不然就会失败。
  • 在不须要经过客户端脚本访问cookie时,使用HTTP-only cookie
  • 请记住外部输入不仅是显式的表单域。
  • 建议使用AntiXSS 编码器。

黑客、解密高手、垃圾邮件发送者、病毒、恶意软件——它们都想进入计算读查看里面的数据。在阅读本段内容时,咱们的电子邮箱极可能已经转发了不少封电子邮件。咱们的端口遭到了扫描,而一个自动化的蠕虫病毒颇有可能正在尝试经过多种操做系统漏洞找到进入PC的途径。因为这些攻击都是自动的,所以它们在不断地探索,寻找一个开放的系统。安全

应用程序的构建基于这样一种假设,即只有特定用户才能执行某些操做,而其它用户则不能执行这些操做。服务器

7.2 使用Authorize 特性登陆

        保护应用程序安全的第一步,同时也是最简单的一步,就是要求用户只有登陆系统才能访问应用程序的特定部分。         Authorize Attribute 是ASP.NET MVC 自带的默认受权过滤器,可用来限制用户对操做方法的访问。    cookie

Tips:身份验证和受权架构

身份验证是指经过某种形式的登陆机制(包括用户名/密码、OpenID、OAuth 等说明自已身份的项)来核实用户身份。网站

受权验证是用来核实登陆站点的用户是否在他们的权限内执行操做。这一般使用一些基于声明的系统来实现。ui

Authorize 特性不带任何参数,只要求用户以某种角色登陆网站。它禁止匿名访问。编码

7.2.1 保护控制器操做

实现安全性的一个好方法是,始终使安全性检查尽量的贴近要保护的对象。可能有其它更高层的检查,但始终都要确保实际资源的安全。

7.2.2 Authorize 特性在表单身份验证和AccountController 控制器中的用法

基本验证信息

        IPrincipal user=httpContext.User;
        if(!user.Identity.IsAuthenticated)
        {return false;}

        if(_usersSplit.Length>0&&!_usersSplit.Contains(user.Identity.Name,StringComparer.OrdinalIgnoreCase))
        {return false;}

        if(_rolesSplit.Length>0&&!_rolesSplit.Any(user.IsInRole))
        {return false;}
        return true;

    

若是用户身份验证失败,就会返回一个HttpUnauthorizedResult 操做结果,它产生了一个 HTTP 401(未受权)的状态码。

7.2.3 Windows Authentication

为使用Intranet 验证选项,咱们须要启用Windows 验证,禁用 Anonymous 验证。

使用全局受权过滤器保障整个应用程序安全

MVC 4中新添加了AllowAnonymous 特性。若是把AuthorizeAttribute 注册为全局过滤器,而且有些方法须要外部访问,那么这些方法只须要使用4中新添加了AllowAnonymous 特性装饰便可。AllowAnonymous 仅对标准的AuthorizeAttribute 有效;对于自定义的受权过滤器,则不必定起做用。全局受权仅对MVC 是全局的

7.3 要求角色成员使用Authorize 特性

Authorize 特性容许指定角色和用户。

Roles 参数能够有多个角色,咱们用‘,’分割:

7.4 扩展用户身份

7.4.1 存储用户额外的信息

Code First 模式下只须要在用户类中添加属性。

7.5 经过OAuth 和 OpenID 的外部登陆

OAuth 和 OpenID 是开放的标准。这些协议容许用户使用他们已有的帐户登陆咱们的网站。

配置网站以支持OAuth 和 OpenID是很是难以实现的,协议复杂,顶级提供器对这两种协议的实现方式不同。MVC 经过在使用Individual User Accounts 身份验证的项目模板中内置支持OAuth 和 OpenID 极大的简化了这一点。

7.5.1 注册外部登陆提供器

使用OAuth 提供器的网站要求咱们把网站注册为一个应用程序。这样它们会提供给咱们一个客户端id 和一个口令。咱们利用OAuth 提供器根据这些信息就能够进行验证。

7.5.2 配置OpenID提供器

由于不用注册,不用填写参数,配置OAuth 提供器是很是简单的。

7.5.3 配置OAuth提供器

7.5.4 外部登陆的安全性

1,可信的外部登陆器

2,要求SSL 登陆

从外部提供器到咱们网站的回调中包含拥有用户信息的安全令牌,这些令牌容许访问咱们的网站。当令牌在Internet 中传递时,使用HTTPS 传输是很是重要的,由于这样能够访问信息拦截。

为访问AccountController 的Login Get 方法并执行HTTPS,支持外部登陆的应用程序应该使用 RequireHttps 特性来使用HTTPS

 

        //
        //GET:/Account/login

        [RequireHttps]
        [AllowAnonymous]
        pulic ActionResult Login(string returnUrl)
        {
        ViewBag.ReturnUrl=returnUrl;
        return View();
        }

    

7.6 Web 应用程序中安全向量

由于Web 应用程序运行在标准的、基于文本的协议(像HTTP和HTML)之上,因此它们特别容易受到自动攻击的伤害。

7.6.1 威胁:跨站脚本(XSS)

1,威胁概述

有两种方法能够实现XSS,一种方法是经过用户将恶意脚本输入到网站中,而这些网站又能够接收“不干净”(unsanitized)的用户输入。另外一种方法是经过直接在页面上显示用户的输入。第一种状况被称为“被动注入”(Passive Injection)。用户把“不干净的”的        内容输入到文本框,并把这些数据保存在数据库中,之后再从新在页面上显示。第二种方法称为“主动注入”,涉及用户直接把“不干净”的内容输入到文本框中,这些输入的内容会马上被显示出来。

2,被动注入

eg:

        "></a><script src="hackScript.js"></script><a href="

    

3,主动注入

eg:

      http://www.meishizouqi.com?Search=<form action=""><input type="text" name="name" /><input type="password" name="password" /><input type="submit" value="登陆" />

    

4,阻止 XSS

1)对全部内容进行HTML 编码

页面上每个输出都应该是通过HTML 编码或HTML 特性编码。

2)Html.AttributeEncode 和 Url.Encode

谨记:永远不要信任用户可以接触到或者使用的一切数据,其中包括全部的表单值、URL、cookie或来自第三方源(如OpenID)的我的信息。此外网站所访问的数据库或服务可能没有通过编码,因此不要轻易相信输入应用程序的任何数据,要尽量的对其编码。

3)JavaScript 编码

黑客能够很随意的利用十六进制转义码随意的向输入内容中插入JavaScript 脚本代码

4)将AntiXSS 库做为ASP.NET 的默认编码器

  • AntiXSS 使用的是一个信任字符的白名单,ASP.NET 默认实现一个有限的不信任字符的黑名单。
  • AntiXSS 的重点是阻止应用程序的漏洞,ASP.NET 关注的是防止HTML 页面显示不被破坏。

在.NET 4.5及更高版本包含 MicroSoft WPL(Web Protection Library)的AntiXSS 编码器。要使用AntiXSS 库须要在 Web.config 的 httpRunTime 中添加如下代码:< httpRuntime ... encoderType="System.Web.Security.AntiXss.AntiXssEncoder,System.Web,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d59a3a"/>

7.6.2 威胁:跨站请求伪造

跨站请求伪造(Cross-Site Request Forgery,CSRF,有时也写做XSRF 表示)要比简单的跨站脚本攻击更具备危险性。

1,威胁概述

eg:

用户退出登陆方法为:/account/Logout

用户将评论中提交这样一个标签<img src="/account/Logout">

浏览器将自动向该地址发送Get 请求。

2,阻止 CSRF 攻击

ASP.NET MVC 提供了阻止 CSRF 攻击的方法。

1)令牌验证

Html.AntiForgeryToken 辅助方法会生成一个加密值做为隐藏的输入元素。

该值会与做为会话cookie 存储在用户浏览器的另外一个值相匹配。在提交表单时,ActionFilter 会验证这两个值是否相匹配。这种方法能够阻止大部分的CSRF 攻击。

2)幂等的GET 请求

一个幂等操做的特色是执行一次和执行屡次的效果是同样的。

通常来讲,仅经过POST 修改数据库中或网站上的内容能够有效防护所有的CSRF 攻击。

3) HttpReferrer 验证

HttpReferrer 验证经过使用ActionFilter 处理。这种状况下能够查看提交表单值的客户段是否在目标站点上。

7.6.3 威胁:cookie 盗窃

若是可以窃取某人在一个网站上的身份验证Cookie,就能够在该网站上冒充他,执行他权限内的全部操做。这种攻击依赖于 XSS 漏洞。攻击者须要在目标站点上注入一些脚本,才能窃取 Cookie

StackOverflow.com 容许在评论中包含提交必定数量的HTML 标记

能够中止脚本对站点中cookie 的访问,须要设置一个简单的标志:HttpOnly

能够在 web.config 文件中对全部的Cookie 设置,也能够为编写的每一个Cookie 单独设置。

7.6.4 威胁:重复提交

重复提交:恶意用户向查询字符串或提交的表单添加超出用户最终操做权限的值。

防护重复提交最简单的一个方法是使用[Bind] 特性显式的控制须要由模型绑定器绑定的属性。也能够用 UpdateModel 或 TryUpdateModel 方法的一个重载版本接受一个绑定列表。

7.6.5 威胁:开放重定向

1.威胁概述

那些经过请求(如查询字符串和表单数据)指向重定向URL 的WEB 应用程序可能被篡改,而把用户重定向到外部的恶意URL。这种篡改就被称为开放重定向攻击(open redirection attack)。

能够调用 IsLocalUrl()方法对 returnUrl 参数进行验证。

7.7 适当的错误报告和堆栈跟踪

customErrors 模式有3 个可选设置项,分别是:

  • On:服务器开发最安全选项,由于它老是隐藏错误提示消息。
  • RemoteOnly:向大多数用户展现通常的错误信息,但向拥有服务器访问权限的用户展现完整的错误提示消息。
  • Off:最容易受到攻击的选项,它向每个网站的访问者展现详细的错误处理。

7.7.1 使用配置转换

使用RemoteOnly 模式替换掉customError 模式。

7.7.2 在生产环境下使用Retail 部署配置

部署配置的是服务器环境下一的 machine.config 文件中的一个简单开关,用来标识ASP.Net 是否在Retail 部署模式下运行。

将deployment/retail 设置为true ,将影响如下几项设置

  • 设置为On,就是最安全的设置
  • 禁用跟踪输出
  • 禁用调试

这些设置能够覆盖Web.config 文件中全部应用程序级别的设置

7.9 小结

Web 应用程序中安全问题老是能够归结为开发人员一方的简单问题:不当的假设、错误信息及缺少训练等。

相关文章
相关标签/搜索