1. 登录用户数据获取
登录成功之后,在后续的业务逻辑中,开发者可能还需要获取登录成功的用户对象,如果不使用任何安全管理框架,那么可以将用户信息保存在HttpSession中,以后需要的时候直接从HttpSession中获取数据。在Spring Security中,用户登录信息本质上还是保存在 HttpSession中,但是为了方便使用,Spring Security对HttpSession中的用户信息进行了封装, 封装之后,开发者若再想获取用户登录数据就会有两种不同的思路:
- 从 SecurityContextHolder 中获取
- 从当前请求对象中获取。
这里列出来的两种方式是主流的做法,开发者也可以使用一些非主流的方式获取登录成功后的用户信息,例如直接从HttpSession中获取用户登录数据,
无论是哪种获取方式,都离不开一个重要的对象:Authentication。在Spring Security中, Authentication对象主要有两方面的功能:
- 作为AuthenticationManager的输入参数,提供用户身份认证的凭证,当它作为一个 输入参数时,它的isAuthenticated方法返回false,表示用户还未认证』
- 代表已经经过身份认证的用户,此时的Authentication可以从SecurityContext中获取。
一个Authentication对象主要包含三个方面的信息:
- principal: 定义认证的用户。如果用户使用用户名/密码的方式登录,principal通常就是一个UserDetails对象。
- credentials:登录凭证,一般就是指密码。当用户登录成功之后,登录凭证会被自动擦除,以防止泄漏。
- authorities:用户被授予的权限信息。
Java中本身提供了 Principal接口用来描述认证主体,Principal可以代表一个公司、个人或者登录ID,Spring Security中定义了 Authentication接口用来规范登录用户信息, Authentication 继承自 Principal:- public interface Authentication extends Principal, Serializable {
- Collection<? extends GrantedAuthority> getAuthorities();
- Object getCredentials();
- Object getDetails();
- Object getPrincipal();
- boolean isAuthenticated();
- void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
- }
复制代码 这段源码中可以看到,SecurityContextHolder定义了三个静态常量用来描述三种不同的存储策略;存储策略strategy会在静态代码块中进行初始化,根据不同的strategyName初始化不同的存储策略;strategyName变量表示目前正在使用的存储策略,开发者可以通过配置系统变量或者调用setStrategyName来修改SecurityContextHolder中的存储策略,调用 setStrategyName 后会重新初始化 strategy。
默认情况下,如果开发者试图从子线程中获取当前登录用户数据,就会获取失败,代码如下:
[code]package com.intehel.demo.controller;import org.springframework.security.core.Authentication;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import java.util.Collection;@RestControllerpublic class UserController { @GetMapping("/user") public void userinfo(){ Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String name = authentication.getName(); Collection |