Spring Security系列(一)简介
Spring Security 是一个强大的和高度可定制的身份验证和访问控制框架,是Spring应用程序的标准安全框架。
1.安全
安全是一个不断移动的目标,采取一个全面的全系统的方法很重要。在安全领域,我们鼓励你采取"layers of security"(安全层),这样每一层尽可能的在自己范围内诶保证安全,连续的层提供额外的安全性。安全层更密集你的程序将更加健壮更加安全。
①应用之外的安全机制:如防火墙,VPN等
在企业环境中你可以部署一个DMZ将面向公众的服务器和数据库以及应用服务器分隔开来。
②应用本身的安全机制:如Sql注入,XSS,逻辑漏洞等
这个层面的安全问题,在程序开发时是可以通过编程解决大部分,项目中使用安全框架,提高单元测试的代码覆盖率。
③应用底层的安全机制:编程语言和技术漏洞等
这个层面的问题自然有更专业的安全专家解决,而且对于java而言自身的安全机制也是很强的。
显然开发人员能够控制的就是应用本身的安全问题,学习常见的Web安全问题和安全框架是每一位开发人员所必须的技能。
2.认证(Authentication)和授权(Authorization)
在学习框架之前,我们先要搞清楚两个核心概念:认证和授权
①认证简单的来讲就是校验身份信息,确定用户身份是否有效
例如使用传统的账号密码校验(类似于appId和密钥)和使用session和token校验等。
说到账号密码校验,就不得不提数据加密的问题,为了确保安全性通常涉及隐私的都是密文存储,尽管使用hash函数得到的摘要密文是不可逆的,但是目前常用的md5,sha256都可以通过查询彩虹表(Rainbow Tables)暴力破解,因此通过加盐来进一步提高密码的复杂度。
②授权简单的来讲就是校验权限,确定有效用户是否有权限访问资源
认证和授权也是RBAC模型的核心部分(学习框架了解RBAC还是很有必要的,Spring Security和Apache Shiro都是基于RBAC模型的安全框架)。
3.Spring Security 能做什么
①综合对认证授权的支持,并且可扩展
②保护常见的攻击:session fixation, clickjacking, cross site request forgery等
③支持ServletAPI,Spring Web MVC等
SpringSecurity包含以下部分:
①spring-security-core.jar 认证授权的核心模块
②spring-security-remoting.jar 整合了Spring Remoting,创建远程客户端时使用
③spring-security-web.jar 过滤器和web安全,支持servlet
④spring-security-config.jar
⑤spring-security-ldap.jar
⑥spring-security-oauth2-core.jar和
spring-security-oauth2-client.jar等
4.PasswordEncoder
PasswordEncoder接口定义了密码加密的顶级接口,老版本的默认加密方式是NoOpPasswordEncoder(默认不加密),而Spring Security 5.0后的默认加密方式为BCryptPasswordEncoder。
Spring Security提供了DelegatingPasswordEncoder(通过PasswordEncoderFactories类创建,也可以模仿PasswordEncoderFactories类自定义)
兼容老版本。
目前Spring Security中建议使用上述四种加密算法,其他算法认为不安全。
5.架构/原理
首先SpringSecurity是基于Filter技术实现的。Spring通过DelegatingFilterProxy建立Web容器和Spring ApplicationContext的联系而SpringSecurity使用FilterChainProxy
注册SecurityFilterChain。
重点研究Spring Security中定义的各种Filter以及执行顺序。
①认证模块
a.SecurityContextHolder(用于存储授权信息)
手动授权的例子(SecurityContextHolder.getContext().setAuthentication(authentication)这种授权方式多线程不安全):
SecurityContext context = SecurityContextHolder.createEmptyContext(); Authentication authentication = new TestingAuthenticationToken("username", "password", "ROLE_USER"); context.setAuthentication(authentication); SecurityContextHolder.setContext(context);
b.AuthenticationManager
除了手动授权外,SpringSecurity通过AuthenticationManager和ProviderManager进行授权。其中AuthenticationProvider代表不同的认证机制(最常用的账号/密码)。
②授权模块
认证完成之后,SpringSecurity通过AccessDecisionManager
完成授权操作。除了全局的授权配置之外,也可以通过@PreAuthorize
, @PreFilter
, @PostAuthorize
, @PostFilter注解实现方法级别的权限控制。
授权的表达式:
6.使用介绍
①基于用户名和密码的认证模式
请求的用户名密码可以通过表单登录,基础认证,数字认证三种方式从HttpServletRequest中获得,用于认证的数据源策略有内存,数据库,ldap,自定义等。
上面两图描述了表单登录的过程,拦截未授权的请求,重定向到登录页面,进行账号密码认证。
7.简单总结
SpringSecurity核心是认证和授权,是基于Filter实现的。