web开发之安全(一)
web开发之安全(beta)
一直都想记录下关于系统开发中的安全问题,但是发现这个话题太大其中会涉及到网络安全、服务器安全、系统安全、数据传输安全等等。整个体系涉及的知识面非常太广泛,然而,很多时候我们只需要在特定的场合解决特定的问题,大多数知识仅仅只需要理解即可,至于其原理以及具体实现,大多原因自己的兴趣与一腔热血才能够深入下去。作为一名Web开发者,即没有从事相关领域的研发经验,又缺乏整体知识体系的储备,姑且将所谓的安全问题限制在web应用开发过程中所牵扯的内容,这样更适合在一个领域将问题弄明白。
从事工作至今,在参与的各种系统建设或应用开发过程中,基本都离不开系统安全模块。我们既要保证用户简单安全的进入系统,又要保证用户提交的密码不被窃取;在微服务盛行的当下,如何保证各个应用系统通过单点登录试下一次登录几个在多个系统间进行切换;或者在与第三方系统集成时,如何快速有效的与接入到其他系统进而实现数据或API交换。在任何行业,安全都是非常重要的环节,特别是信息化产业或互联网应用中,面对网络这个开放,广袤的环境,随时都会有各种信息与我们的系统进行数据通信,建设安全可靠的Web应用是每个开发者必须具备的技能。
认证与授权
web应用的开发,主要是为用户提供一套处理、管理与应用数据的平台。数据就是用户的最终的资产,而数据可以存储到数据库、文件、内存或其它介质上,为了使数据具有生产价值,我们需要依托于各种应用实现数据交换,通过数据的流动产生业务价值。比如在CMS(内容管理系统)中,我们需要通过系统将各种内容信息包括文件、表格、图片、视频等数据管理并为内容提供多样化、可适配、可维护的展示形式供使用;在OA(自动化办公平台)系统中,需要对日常办公各个环节进行流程化管理,实现工作的流程化与规范化。整个过程中都是用户面向系统。
我觉得web应用的安全问题关注点主要有两个方面,一是围绕用户对系统的访问,即认证,对访问系统用户身份的核实;二是围绕数据操作,即鉴权,对具有操作权限的主体进行校验。
下面会围绕着认证(Authentication)与授权(Authorization)两个方面展开,主要会聊到现在应用在用户认证上的主要形式,一些主流的协议以及技术实现。
登录认证的形式
在访问网站或者登录手机APP时,系统经常需要我们登录并且认证成功后才能访问到系统受限的内容,比如淘宝我们可以通过手机端的淘宝APP扫描登录,比如微信我们可以通过账号+密码;手机号+验证码等方式进行登录,或者类似于知乎这样可以通过微信、QQ、微博第三方平台进行认证的。



目前接触的主要的身份验证形式包括:
1.用户名和密码
- 根据注册名、邮箱、手机号等唯一名称加上密码进行登录,是一种最为普及的登录形式,基本所有WEB应用都会支持。这种方式实现简单,同时安全问题严重。现在浏览器基本都支持用户名、密码保存的功能,当服务器数据被盗取后就非常危险。同时在登录提交数据时,当提交的用户名密码信息被人劫取,一样存在风险。
- 优点:使用简单,只需要记住一组登录名和密码就可以登录系统
- 缺点:用户需要注册新用户,需要输入各种信息以及信息的校验,登录名是不重复的;任何人知道登录名和密码即可登录系统,一断密码泄露会带来安全问题;
2.手机号和验证码
- 手机号加验证码方式的登录在互联网应用中使用非常频繁,一般结合用户名密码作为登录验证的一个环节。通过该种方式可以记录用户的手机号信息,进而衍生了新的业务价值,比如推送营销短信,同时现在手机号都需要实名认证,可以保证用户的有效与真实性。
- 优点:简单,不需要用户注册,通过提供能接收短信有效的手机号码即可完成系统登录。安全性较低,动态码泄露,后果比较严重
- 缺点:依赖于手机。发送手机短信增加了运营成本。依赖于短信运行商,如果出现问题会导致整个系统无法登陆。
3.OTP(动态令牌认证系统)
- 基于一定的算法生成具有有效时长、一次性的动态随机密码。手机号+验证码就是一种OTP认证的表现。
- 优点:动态码的生成方式更加安全,传输方式更加多样化,
- 缺点:依赖于动态码接收终端。增加了服务端验证成本,需要提供一套动态码生成与校验组件来支持
4.第三方认证
- 互联网应用基本都提供了第三方认证的支持,主要是借助一些主流、广泛、可靠的平台比如微信、QQ、微博、支付宝完成用户身份认证,系统本身不用单独开发改功能。
- 优点:通过第三方完成用户身份的认证,免去了用户注册流程,一个账号可以实现多个平台的登录。
- 缺点:系统需要按照第三方认证规范集成。依赖于第三方平台的稳定性,如果出现故障对自己系统造成影响。用户的信息都是来源于第三方,没有保存到本系统。
5.二维码
- 一般在登录微信、支付宝等应用时常见,通过移动端已经认证过的APP扫描WEB端的二维码完成登录。一般都是自家系统移动端与PC端的集成,关于二维码的仿造、劫持以及攻击则属于网站本身安全问题。
在淘宝、京东等平台上,目前都支持扫描登录,可见该登录形式也是被各种大厂接收并广泛使用。 - 优点:扫码即登录,免去了用户名、密码输入;
- 缺点:需要对应的APP支持,同时需要开发二维码登录认证流程
6.指纹识别|人脸识别|语音识别
- 改技术主要是通过一些技术手段(光电技术、微计算机技术和图像处理技术)分析人体生物特征,生成一组代表认证主题的数据,包含了用户的身份与密钥两个部分
- 优点:简单,通过生物特征实现快速认证,免去了普通登录模式信息记录的麻烦
- 缺点:需要额外的硬件支持
协议与规范
登录的形式都是在前端页面上体现给用户的,但具体的登录流程这需要开发者根据实际的系统需求进行选择,我们经常会在简易程度与安全上做一定的权衡,一般安全性越高的系统,在实现用户身份认证上都会比较复杂。作为开发者,选择怎样的技术实现往往由很多因素决定。比如手机端我们可以选择指纹识别;人脸识别等技术,主要是操作上更加的便捷;针对部署在内网的系统,我们可以使用简单的用户名密码方式,因为网络环境受限不容易被攻击,从而安全性本身就得到保证;但像金融系统,对数据安全性就非常高,往往会在用户名密码的基础上添加一些动态验证或生物识别技术等多因子认证手段。
在单体应用中,我们往往通过用户名密码基于cookie/session机制即可实现用户的认证。但实际的环境中我们会面对各种系统间的通信,传统的认证方式显得非常的局限,为了实现高可用、安全、可靠,易维护的认证系统,必须在各个环节都需考虑周全,因此在技术不断的发展过程中,形成了一系列认证协议与授权模型,这些是前人经验的总结,同时也是统一的规范。
安全认证协议:
-
OAuth2
一种第三方认证协议
允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站在特定的时段内访问特定的资源。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。 -
OpenID
去中心化的网上身份认证系统
OpenID是一个去中心化的网上身份认证系统。对于支持OpenID的网站,用户不需要记住像用户名和密码这样的传统验证标记。取而代之的是,他们只需要预先在一个作为OpenID身份提供者(identity provider, IdP)的网站上注册。OpenID是去中心化的,任何网站都可以使用OpenID来作为用户登录的一种方式,任何网站也都可以作为OpenID身份提供者 -
OIDC
基于 OAuth 2.0 的认证 + 授权协议
OIDC 在 OAuth 协议上进行了扩展,主要组件包括 OAuth 协议的基础框架加上具有唯一性的用户工作流。OIDC 让客户端服务也就是应用通过 OpenID 验证服务器核验用户身份并通过 RESTful API 交换配置文件信息,这些 API 会分派 JSON Web 令牌(JWT)用于身份验证过程中的信息共享。 -
SAML
安全断言标记语言
SAML 是一种用于身份验证和授权的开放标准,通过身份联合提供对 Web 应用的单点登录访问。SAML 从 IdP 中继用户凭证来验证访问权限和 SP,其中服务提供提供程序(SP)需要在授予用户访问权限之前进行身份验证。每个用户或组都有各自的属性概括了配置文件信息,并声明具体的访问权限。 -
CAS
中央认证服务
CAS协议是一种简单且功能强大的基于票证(ticket)的协议。它涉及一个或多个客户端和一台服务器。中央身份验证服务(CAS)是Web的单点登录/单点退出协议 -
LDAP
轻量目录访问协议
LDAP是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息。目录服务在开发内部网和与互联网程序共享用户、系统、网络、服务和应用的过程中占据了重要地位。
权限访问模型:
-
ACL
权限访问列表。通过权限限制操作,用户直接和权限关联 -
RBAC
基于角色的访问控制。权限关联角色,通过不同角色控制用户的访问权限 -
ABAC
基于属性权限访问控制。
用户属性(如用户年龄),环境属性(如当前时间),操作属性(如读取)和对象属性(如一篇文章,又称资源属性),所以理论上能够实现非常灵活的权限控制,几乎能满足所有类型的需求。
技术选择
目前WEB开发主要有遵循Http协议的基于Servlet开发的服务;或是为实现高性能RPC协议基于NIO模型的网络通信应用。
在基于Servlet开发中,基本都是通过定义各种过滤器(Filter)来实现用户身份的认证,在过滤器中完成用户身份(登录名),用户密码(令牌、密码、动态码)的校验,而用户的鉴权则基于AOP实现,在用户对具体资源操作时能够做出对应响应。现阶段比较知名的安全框架包括:
-
Appache Shiro
Apache Shiro是一个功能强大且灵活的开源安全框架,可以干净地处理身份验证、授权、企业会话管理和加密,提供了一种直观,全面的身份验证、授权、加密和会话管理解决
- 简单的API调用实现验证过程
- 丰富的异常定义认证失败原因
- 多种开箱即用的数据源集成,比如JDBC、LDAP、Active Directory
- 提供多维度用户验证逻辑
- 实现了基于角色、权限的鉴权机制
- 灵活的定义与使用权限模型
- 为加密提供了简化的API
- 提供了可扩展的会话管理实现简单的集群
- 实现与桌面应用的会话集成
- 通过简单的Filter集成到WEB环境
- 与其他框架集成,如Spring、Guice、CAS
- ...
-
Spring Security
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
- 多样化的密码加密策略
- 防止CSRF攻击
- 默认支持多种Http响应头提高系统安全性性
- 提供了与其他框架或API的集成,比如Cryptography、Spring Data、Concurrency、Jackson、Localization
- 丰富的内置过滤器
- 开箱即用,通过和SpringBoot集成,简单的几行代码即可实现基础的认证服务
- ...
-
Keycloak
Keycloak为Web应用和Restful服务提供了一站式的单点登录解决方案。它的目标就是让应用的安全管理变得简单,让开发人员可以轻松地保护他们的应用程序和服务。并且Keycloak为登录、注册、用户管理提供了可视化管理界面,你可以借助于该界面来配置符合你需要的安全策略和进行用户管理。
- 浏览器应用程序的单点登录(SSO)。
- OIDC认证授权。
- OAuth 2.0。
- SAML。
- 多租户支持。
- 身份代理 - 使用外部 OpenID Connect 或 SAML 身份提供商进行身份验证。
- 第三方登录。
- 用户联盟 - 从 LDAP 和 Active Directory 服务器同步用户。
- Kerberos 网桥 - 自动验证登录到 Kerberos 服务器的用户。
- 用于集中管理用户、角色、角色映射、客户端和配置的管理控制台。
- 用户账户集中管理的管理控制台。
- 自定义主题。
- 两段身份认证。
- 完整登录流程 - 可选的用户自注册、恢复密码、验证电子邮件、要求密码更新等。
- 会话管理 - 管理员和用户自己可以查看和管理用户会话。
- 令牌映射 - 将用户属性、角色等映射到令牌和语句中。
- 安全策略恢复功能。
- CORS 支持 - 客户端适配器具有对 CORS 的内置支持。
- 自定义SPI接口扩展。
- JavaScript 应用程序、WildFly、JBoss EAP、Fuse、Tomcat、Jetty、Spring 等客户端适配器。
- 支持任何具有 OpenID Connect Relying Party 库或 SAML 2.0 Service Provider 库的平台/语言
-
JCasbin
Casbin是一个强大的、高效的开源访问控制框架,其权限管理机制支持多种访问控制模型,如ACL,RBAC,ABAC,MAC
- 以经典形式或自定义形式强制实施策略,如您定义的那样,都支持允许和拒绝授权。
- 处理访问控制模型及其策略的存储。
- 管理角色-用户映射和角色-角色映射(也称为 RBAC 中的角色层次结构)。
- 支持内置超级用户如 或 .超级用户可以在没有显式权限的情况下执行任何操作。rootadministrator
- 多个内置运算符支持规则匹配。例如,可以将资源键映射到模式
其中Apache Shiro、Spring Security、Keycloak都是基于Servlet API实现,在web开发过程中比较容易集成,在这些框架包括了安全认证与鉴权两个模块,提供了丰富的功能与简单的API,在网上有大量的示例与技术文档为开发者提供帮助。
jCasbin没有实现身份认证的功能,但为丰富的鉴权模型提供了支持。
结束语
web认证涉及到的知识面还是非常有深度的,在学习相关知识的同时,会发现很多技术框架都是基于一些成熟的规范去实现并不断演变。随着互联网的发展,越来越多的安全问题暴露出来,有些是因为技术本身的却邪,有些是不可预料的安全漏洞,如何实现简单且可靠的应用不是一蹴而就的事情。
由于篇幅的限制以及认知的约束,仅仅简单地对接触到的内容做了一些的总结,描述了一些概念性的东西,其中每个知识点可能都需要大篇幅的内容描述才能说的清楚,因此并没有深入地讲解实现原理以及实际的应用场景,在后续的学习过程中,会深入浅出地从原理到应用,将各种协议、技术在实际项目中得以体现。
参考
https://en.wikipedia.org/wiki/Access_control
http://www2.imm.dtu.dk/courses/02230/AdvancedAccessControl.pdf
https://openid.net/specs/openid-connect-core-1_0.html
https://shiro.apache.org/index.html
https://docs.spring.io/spring-security/reference/index.html

浙公网安备 33010602011771号