引言
安全问题不管在任何行业与领域,一直都是备受关注的话题,当出现安全问题时,往往都伴随着人身、财产、资源等等遭受损害。在IT领域,你可能会接触到网络安全、服务器安全、系统安全、数据传输安全等等,其中任何一个都可以是一个有深度的话题。
今天讲到的内容,可以说在Web应用开发中我们最为常见的主题安全,为了保证我们的Web应用能够安全地为合法的用户提供限定的服务,我们需要处理的安全问题可以拆分为解决用户认证与访问授权。
概要
从事工作至今,在参与的各种系统建设或应用开发过程中,基本都离不开系统安全模块。可能你没有参与该模块的开发,但应该有参与相关的系统集成、模块的引用、参数的配置等工作。
- 如何既保证用户能够简单地进入系统,又要保证用户提交的信息不被窃取;
- 既要保证用户能够正常地访问到数据,又要保证访问的数据不能越权;
- 在应用集群环境中,如何保证各个应用系统通过一次登录即可完成多个系统间的相互访问;
- 在有第三方系统需要集成或与第三方系统进行集成时,如何快速有效的与其他系统保证数据的交互;
作为一名优秀的开发者,能够解决这些问题都是我们应该具备的技能。
本篇文章作为《Web认证与授权》系列的开篇章,主要简单地介绍了一些与之相关的内容,比如上面说到的认证授权的基本定义;前端常见的认证形式;与之相关的一些规范与协议;在Java中的一些技术实现框架等等。
认证与授权
Web安全模块的核心是什么?
我觉得该问题的关注点主要有两个方面:一是围绕用户对系统的访问,即认证(Authentication),对访问系统用户身份的核实;二是围绕资源操作,即鉴权(Authorization),对鉴定操作主体是否对限定资源有操作权限。
登录的形式
如何实现认证?一般情况,认证即对用户登录身份的校验。访问网站时,在进行一些重要操作时,系统经常需要我们登录完成后才行,比如淘宝会引导我们进入登录页面,可以通过淘宝APP扫码,用户名密码等形式,确认用户身份后才能进行像添加购物车,购买等操作。
下面我们来看看一些大厂的登录页面
- 百度登录
支持APP扫码,账号密码,短信动态码,QQ微博微信
- 淘宝登录
支持APP扫码,账号密码,手机号动态码,微博支付宝
- 腾讯云登录
可能由于微信的盛行,扫码成立腾讯云或其他产品最为广泛的登录形式,当然像邮箱、QQ、小程序同样是支持的,但感觉都在腾讯的圈圈中...
腾讯云的登录页
可见主流的大厂,在登录认证这块,还是集成了非常多的方式供用户选择,主要还是为了方便,当然你要是打开控制台,你会发现提交的数据(特别是用户名密码)都是经过加密处理了
认证的形式
用户名和密码
- 根据注册名、邮箱、手机号等唯一名称加上密码进行登录,是一种最为普及的登录形式,基本所有WEB应用都会支持。这种方式实现简单,同时安全问题严重。现在浏览器基本都支持用户名、密码保存的功能,当服务器数据被盗取后就非常危险。同时在登录提交数据时,当提交的用户名密码信息被人劫取,一样存在风险。
- 优点:使用简单,只需要记住一组登录名和密码就可以登录系统
- 缺点:用户需要注册新用户,需要输入各种信息以及信息的校验,登录名是不重复的;任何人知道登录名和密码即可登录系统,密码泄露会带来严重的安全问题;
手机号和验证码
- 手机号加验证码方式的登录在互联网应用中使用非常频繁,一般结合用户名密码作为登录验证的一个环节。通过该种方式可以记录用户的手机号信息,进而衍生了新的业务价值,比如推送营销短信,同时现在手机号都需要实名认证,可以保证用户的有效与真实性。
- 优点:简单,不需要用户注册,通过提供能接收短信有效的手机号码即可完成系统登录。
- 缺点:依赖于手机。发送手机短信增加了运营成本。依赖于短信运行商,如果出现问题会导致整个系统无法登录。
OTP(动态令牌认证系统)
- 基于一定的算法生成具有有效时长、一次性的动态随机密码。手机号+验证码就是一种OTP认证的表现。
- 优点:动态码的生成方式更加安全,传输方式更加多样化,
- 缺点:依赖于动态码接收终端。增加了服务端验证成本,需要提供一套动态码生成与校验组件来支持
第三方认证
- 互联网应用基本都提供了第三方认证的支持,主要是借助一些主流、广泛、可靠的平台比如微信、QQ、微博、支付宝完成用户身份认证,系统本身不用单独开发改功能。
- 优点:通过第三方完成用户身份的认证,免去了用户注册流程,一个账号可以实现多个平台的登录。
- 缺点:系统需要按照第三方认证规范集成。依赖于第三方平台的稳定性,如果出现故障对自己系统造成影响。用户的信息都是来源于第三方,没有保存到本系统。
二维码
- 一般在登录微信、支付宝等应用时常见,通过移动端已经认证过的APP扫描WEB端的二维码完成登录。一般都是自家系统移动端与PC端的集成,关于二维码的仿造、劫持以及攻击则属于网站本身安全问题。在淘宝、京东等平台上,目前都支持扫描登录,可见该登录形式也是被各种大厂接受并广泛使用。
- 优点:扫码即登录,免去了用户名、密码输入;
- 缺点:需要对应的APP支持,同时需要开发二维码登录认证流程
指纹识别|人脸识别|语音识别
- 该技术主要是通过一些技术手段(光电技术、微计算机技术和图像处理技术)分析人体生物特征,生成一组代表认证主题的数据,包含了用户的身份与密钥两个部分
- 优点:简单,通过生物特征实现快速认证,免去了普通登录模式信息记录的麻烦
- 缺点:需要额外的硬件支持
协议与规范
登录的形式都是在前端页面上体现给用户的,但具体的登录流程则需要开发者根据实际的系统需求进行选择,我们经常会在简易程度与安全上做一定的权衡。
一般安全性越高的系统,在实现用户身份认证上都会比较复杂。
作为开发者,选择怎样的技术实现往往由很多因素决定。比如手机端我们可以选择指纹识别;人脸识别等技术,主要是操作上更加的便捷;针对部署在内网的系统,我们可以使用简单的用户名密码方式,因为网络环境受限不容易被攻击;但像金融系统,对数据安全性就非常高,往往会在用户名密码的基础上添加一些动态验证或生物识别技术等多因子认证手段。
认证协议:
- 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
- 以经典形式或自定义形式强制实施策略,如您定义的那样,都支持允许和拒绝授权。{subject, object, action}
- 处理访问控制模型及其策略的存储。
- 管理角色-用户映射和角色-角色映射(也称为 RBAC 中的角色层次结构)。
- 支持内置超级用户如 或 .超级用户可以在没有显式权限的情况下执行任何操作。rootadministrator
- 多个内置运算符支持规则匹配。例如,可以将资源键映射到模式
其中Apache Shiro、Spring Security、Keycloak都是基于Servlet API实现,在web开发过程中比较容易集成,在这些框架包括了安全认证与鉴权两个模块,提供了丰富的功能与简单的API,在网上有大量的示例与技术文档为开发者提供帮助。jCasbin没有实现身份认证的功能,但为丰富的鉴权模型提供了支持。
结束语
web认证涉及到的知识面还是非常有深度的,在学习相关知识的同时,会发现很多技术框架都是基于一些成熟的规范去实现并不断演变。随着互联网的发展,越来越多的安全问题暴露出来,有些是因为技术本身的缺陷,有些是不可预料的安全漏洞,如何实现简单且可靠的应用不是一蹴而就的事情。
开篇让我们对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://oauth.net/2/
- https://shiro.apache.org/index.html
- https://docs.spring.io/spring-security/reference/index.html
- https://www.keycloak.org/documentation.html
- https://casbin.org/