Spring Security Core

本文深入探讨了Spring Security框架的核心组件,包括SecurityContextHolder、SecurityContext、Authentication、GrantedAuthority和UserDetails等,阐述了它们在实现应用安全控制中的作用和工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring Security Core

核心组件

  • SecurityContextHolder,提供访问SecurityContext的
  • SecurityContext,存储Authentication 和可能的请求安全信息
  • Authentication,表示在Spring Security机制中的一个访问者
  • GrantedAuthority,反映访问者在应用范围的权限
  • UserDetails,提供必要的信息来构建Authentication对象,例如从应用的DAO 或者安全相关的数据源
  • UserDetailsService,通过传递基于字符串的用户名称(或者证书ID等)创建UserDetails

SecurityContextHolder

SecurityContextHolder是最基础的对象,我们用来存储表示当前应用安全的上下文信息,包含当前访问者的详情。默认情况,SecurityContextHolder使用ThreadLocal来存储这些详情,这意味着security context在同一个执行线程中是可以一直有效的,即使security context没有作为参数显示地传递到其他方法中。使用ThreadLocal比较安全,它会在当前访问者请求进程结束时被清理。

有些应用不适合使用一个ThreadLocal,它们可能使用别的方式处理线程,例如,一个Swing客户端可能要求JVM中所有线程使用同一个Security Context。SecurityContextHolder可以再启动的时候配置不同策略,来指定我们想如何存储上下文信息。例如一个单应用可能使用SecurityContextHolder.MODE_GLOBAL策略。其他应用可能要求线程从同一个secure thread继承,这时,可以设置为SecurityContextHolder.MODE_IHERITABLETHREADLOCAL。有两种方式来变默认的SecurityContextHolder.MODE_THREADLOCAL,一是设置系统属性,二是调用SecurityContextHolder的静态方法。大多数情况不需要改变默认的策略。

通过SecurityContextHolder我们可以获取当前访问者的信息,Spring Security使用一个Authentication对象来表示这些信息。我们不需要自己来创建这个Authentication对象,但是比较常见的是查询Authentication对象。例如:

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof UserDetails) {
	String username = ((UserDetails)principal).getUsername();
} else {
	String username = principal.toString();
}

UserDetailsService

我们可以从Authentication对象中获取访问者信息,访问者是一个Object,一般情况下,可以转换为UserDetailsUserDetails是Spring Security核心接口。它表示访问者,但也支持扩展,可以把UserDetails理解为我们自己用户数据与Spring Security所需的适配器。我们可以强转为我们自己的对象。

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserInfoRepository repository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<UserInfo> user =
                repository.findByUsername(username);

        return user.orElseThrow(() ->
                new UsernameNotFoundException("user does not exists"));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值