Spring Security

frameSpring

# 一、安全框架

Java流行的安全框架有两种Apache ShiroSpring Security

Apache Shiro 官网:https://shiro.apache.org (opens new window)

Spring Security 官网:https://spring.io/projects/spring-security (opens new window)

# 二、Shiro

Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证、授权、管理会话以及密码加密。

如下是它所具有的特点:

  1. 易于理解的 Java Security API;

  2. 简单的身份认证(登录),支持多种数据源(LDAP,JDBC,Kerberos,ActiveDirectory 等);

  3. 对角色的简单的签权(访问控制),支持细粒度的签权;

  4. 支持一级缓存,以提升应用程序的性能;

  5. 内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境;

  6. 异构客户端会话访问;

  7. 非常简单的加密 API;

  8. 不跟任何的框架或者容器捆绑,可以独立运行。

# 三、Spring Security

Spring Security是 Spring 家族中的一个安全管理框架

Spring Security 官方对自己介绍如下:

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它是保护基于Spring的应用程序的事实标准。

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirementsSpring

Security是一个专注于为Java应用程序提供身份验证和授权的框架。与所有Spring项目一样,Spring Security的真正威力在于它可以多么容易地扩展以满足定制需求

一般Web应用的需要进行认证和授权。

  • 认证(Authentication):验证当前访问系统的是不是本系统的用户,并且要确认具体是哪个用户;

  • 授权(Authorization):经过认证后判断当前用户是否有权限进行某个操作。

而认证和授权就是SpringSecurity作为安全框架的核心功能。它提供了完善的认证机制和方法级的授权功能。是一款非常优秀的权限管理框架

它的核心是一组过滤器链,不同的功能经由不同的过滤器。

# 单点登录

单点登录就是在一个多应用系统中,只要在其中一个系统上登录之后,不需要在其它系统上登录也可以访问其内容

# RSA

非对称加密算法RSA

RSA的基本原理有两点:

  • 私钥加密,持有私钥或公钥才可以解密
  • 公钥加密,持有私钥才可解密

# JWT

JSON Web Token JWT

JWT是一种用于通信双方之间传递安全信息的简洁的、URL安全的表述性声明规范。

一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。

最终生成的JWT令牌就是下面这样,有三部分,用 . 分隔。

base64UrlEncode(JWT 头)+“.”+base64UrlEncode(载荷)+“.”+HMACSHA256(base64UrlEncode(JWT 头) + “.” + base64UrlEncode(有效载荷),密钥)

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
1
2
3

# token过期刷新机制

需求:

对于登录用户签发其对应的token,然后会设置token固定的有效时间。

当token有效期内请求携带toekn验证通过可以进行正常访问,而当token失效后,用户需要重新登录再获取新的token。

那么如果我们token时间设置得短,假如只有10分钟,那么用户当问期间每隔10分钟就要重新登录一次,这样对于用户来说是比较差的体验。

那么就需要一种方案,在前端用户无感知的情况下实现token的自动续期,避免频繁登录、表单填写内容丢失情况的发生。

分析:

  • 用户登录时,为登录用户签发JWT(Json Web Token),并设置JWT的有效时间;
  • 同时将该用户的JWT保存至redis缓存中,并设置缓存的有效期,缓存中保存的JWT的有效期要大于JWT本身的有效时间。
  • 在前端进行本地存储至localstorage或者cookie中,以便后续所有请求携带该token。
  • 当前端携带token发起请求调用资源时,后端进行token合法校验;
  • 无效token则直接返回异常码,校验通过再进行验证token是否过期
  • token有效则直接放行
  • 若token已过期再判断缓存redis中是否存在该token
  • 若缓存redis中也没有,则表示该用户长时间未进行操作,直接抛出token过期,请重新登录
  • 若缓存redis中有,则再获取到redis中的该用户信息,然后重新生成新的token,并设置有效时间,
  • 将redis中原有token进行删除,将新的token再存储至缓存中。
  • 将新的token返回给前端,前端再替换新的token重新发起请求获取资源。

# 验证token流程

用户进行接口请求时,需要携带token,而此时进行接口请求时通常有以下几种状态:

  1. 未携带token传入:返回token为空,非法请求;
  2. 错误token传入:返回非法请求/token签名错误;
  3. 正常token传入:通过 。
  4. 正常token但已过期:查询redis中该token是否存在,如果缓存中存在则刷新token,并将刷新后的token重新放入redis,使用刷新后的token请求资源;
  5. 缓存中不存在,则token刷新期限已过,用户需重新登录。