1、 Spring Security图解,总的来说就是一堆的过滤器。
在没有Spring Security的时候,我们直接访问REST APi可以得到结果,但是当我们的应用加入了Spring security之后,相当于加上了过滤器,其实Spring Security本身就是一个过滤器链,所有的请求在访问REST API时都要经过Spring Security的过滤器链,当返回应答的时候,也会走一遍这个过滤器链,然后返回给用户。
2、 Spring Security 核心组件
(1)spring security核心组件有:SecurityContext、SecurityContextHolder、Authentication、Userdetails 和 AuthenticationManager,下面分别介绍。
(2)SecurityContext:安全上下文,用户通过Spring Security 的校验之后,验证信息存储在SecurityContext中。
(3)SecurityContextHolder:SecurityContextHolder看名知义,是一个holder,用来hold住SecurityContext实例的。在典型的web应用程序中,用户登录一次,然后由其会话ID标识。服务器缓存持续时间会话的主体信息。SecurityContextHolder.getContext().setAuthentication(token);其作用就是存储当前认证信息。
(4)Authentication:authentication 直译过来是“认证”的意思,在Spring Security 中Authentication用来表示当前用户是谁,一般来讲你可以理解为authentication就是一组用户名密码信息。因此可以推断其实现类有这4个属性。这几个方法作用如下:
getAuthorities: 获取用户权限,一般情况下获取到的是用户的角色信息。
getCredentials: 获取证明用户认证的信息,通常情况下获取到的是密码等信息。
getDetails: 获取用户的额外信息,(这部分信息可以是我们的用户表中的信息)
getPrincipal: 获取用户身份信息,在未认证的情况下获取到的是用户名,在已认证的情况下获取到的是 UserDetails (UserDetails也是一个接口,里边的方法有getUsername,getPassword等)。
isAuthenticated: 获取当前 Authentication 是否已认证。
setAuthenticated: 设置当前 Authentication 是否已认证(true or false)。
(5)UserDetails:UserDetails,看名知义,是用户信息的意思。
方法含义如下:
getAuthorites:获取用户权限,本质上是用户的角色信息。
getPassword: 获取密码。
getUserName: 获取用户名。
isAccountNonExpired: 账户是否过期。
isAccountNonLocked: 账户是否被锁定。
isCredentialsNonExpired: 密码是否过期。
isEnabled: 账户是否可用。
(6)UserDetailsService
提到了UserDetails就必须得提到UserDetailsService, UserDetailsService也是一个接口,且只有一个方法loadUserByUsername,他可以用来获取UserDetails。通常在spring security应用中,我们会自定义一个CustomUserDetailsService来实现UserDetailsService接口,并实现其public UserDetails loadUserByUsername(final String login);方法
(7)AuthenticationManager
AuthenticationManager 的作用就是校验Authentication,如果验证失败会抛出AuthenticationException 异常。
3、执行流程
登录流程:
(1) 根据用户名密码创建令牌对象JwtAuthenticationToken(尚无权限数据)。
(2) 根据令牌对象执行登录认证,UserDetailsService调用loadUserByUsername方法获取用户权限信息,返回Authentication(认证信息)。
(3) 认证成功后,存储认证信息到上下文。
(4) 根据Authentication(认证信息)生成token,返回给客户端。
请求流程:
(1) 请求携带token,解析token,获取Claims,如果token错误或者过期,则会出现异常。
(2) 根据token获取认证信息,将认证信息存储到上下文。
(3) 访问接口。
说明:菜单按钮权限信息(sys:menu:add)可以存储在token中,每次请求的时候可以不用再查询数据库获取。