spring-security(九)-核心组件

前言:
  本文主要介绍在spring security中的几个核心组件,以及他们之间是怎样相互协作的。
环境:
  spring boot 版本:1.5.4.RELEASE

1.核心组件之SecurityContextHolder
  SecurityContextHolder是spring security中最基本的组件,是用来存储我们应用的安全上下文的,包含了当前系统认证用户的详细信息。默认情况下SecurityContextHolder用一个ThreadLocal来存储这些详情,这意味着只要是在认证线程中执行的方法,不管我们传不传入这个安全上下文我们都能访问到。
  如果使用ThreadLocal不能完全满足我们系统的需求,可以用以下两种方式来设置SecurityContextHolder的存储模式
  • 通过设置系统变量spring.security.strategy的属性
  • 直接调用SecurityContextHolder的setStrategyName方法,这是个静态方法

spring security目前给我们提供的存储方式有以下三种
  • MODE_THREADLOCAL 默认存储方式,利用ThreadLocal存储
  • MODE_INHERITABLETHREADLOCAL 表示从安全线程中衍生出来的线程也采用和安全线程共享安全上下文
  • MODE_GLOBAL 在整个java 虚拟机里面共享同一个安全上下文,如swing桌面应用中采用

2.核心组件之Authentication对象
  我们把当前系统的认证用户信息存储在了SecurityContextHolder,在spring security内部是使用Authentication来代表这个认证信息的。通常情况下我们不需要自己创建Authentication对象,但是我们经常需要获取这个对象以获取认证者的某些详情(用户名等)。在我们应用代码中的任何地方,我们都可以用如下代码段来获取这个信息
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
String username = ((UserDetails)principal).getUsername(); } else {
String username = principal.toString();
}

SecurityContextHolder.getContext这个方法返回的是SecurityContext,也就是我们的安全上下文信息,如前所述,这个信息默认存储在ThreadLocal中。在spring security中,大多数的认证机制代表的认证信息都是一个UserDetails的具体实例
3.核心组件之UserDetailsService
  从之前获取认证信息的代码片段中我们可以看到从Authentication中获取到的认证主体是一个个对象,并且大多数情况下这个对象能转换成UserDetails对象。UserDetails是一个重要的接口,我们可以把他想象成一个适配器,用来将我们自己数据库中的用户对象适配成spring security 在SecurityContextHolder中存储的对象。有时候我们也会将UserDetails这个对象强制转换成我们系统中提供的原始对象从而获取我们业务特定的用户信息(邮箱、电话等)。
  UserDetailsService就是用来创建UserDetails的组件。这是一个接口,里面只有一个方法
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;

这是spring security中最常用来获取用户信息的地方。
  当用户认证成功后,UserDetails会被用来构建一个Authentication对象,并存储在SecurityContextHolder中,在spring security中,已经为我们提供了很多UserDetailsService的默认实现,如利用内存存储用户信息的InMemoryDaoImpl和利用JDBC存储的JdbcDaoImpl,我们也可以通过实现UserDetailsService这个接口来定制化我们的认证用户信息,并且不管是使用spring为我们提供的,还是我们自定义实现,我们都可以从SecurityContextHolder中获取这个认证信息。
4.核心组件之GrantedAuthority
  除了获取认证主体,Authentication中还有一个重要的方法getAuthorities(),这个方法会放回一个GrantedAuthority数组,一个GrantedAuthority就是赋给认证主体的一个权限,通常这个权限会用一种角色代表,如ROLE_USER、ROLE_ADMIN。这些权限在spring security的鉴权阶段将会被解析,从而判断用户是否具有访问哪些受限制的资源。权限信息通常也是有UserDetailsService的实现类来获取的
  通常情况下GrantedAuthority对象都是应用层面的权限,并不会特指某一个具体的业务对象。因此你不可能会创建一个GrantedAuthority来代替能访问Id号是54的Employee对象,如果这样使用,你会有成百上千的GrantedAuthority来代替不同的业务对象,系统内存将很快被耗尽。
5.总结
  • SecurityContextHolder,存储安全上下文,提供访问SecurityContext的方法
  • SecurityContext,持有Authentication对象,通常情况下代表着特定请求的认证详情(ThreadLocal的存储模式)
  • Authentication,在spring security代表着认证主体
  • GrantedAuthority,代表着付给用户的一种应用级别的许可信息
  • UserDetails,提供必要的信息来构建一个Authentication
  • UserDetailsService,通过传入的用户名称或者证书ID来获取一个UserDetails

猜你喜欢

转载自fengyilin.iteye.com/blog/2411035
今日推荐