

package cn.cy.controller;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
// 此处的 User是SpringSecurity提供的一个封装用户的类
@RequestMapping("/getUser")
public User getUser(){
// SecurityContext 安全上下文. 用来存储认证授权的相关信息(账号信息和相关权限)
SecurityContext context = SecurityContextHolder.getContext();
// Authentication 封装了登录用户信息的对象
Authentication authentication = context.getAuthentication();
// 基于认证对象获取用户身份信息
User user = (User)authentication.getPrincipal();
System.out.println(user);
return user;
}
}


package cn.cy.controller;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
// 此处的 User是SpringSecurity提供的一个封装用户的类
@RequestMapping("/getUser")
public UserDetails getUser(@AuthenticationPrincipal UserDetails user){
System.out.println(user);
return user;
}
}

安全上下文,这个接口可以设置(setter)或者获取(getter)当前的认证对象。
SecurityContext源码:
public interface SecurityContext extends Serializable {
/**
* 获取当前经过身份验证的主体,或身份验证请求令牌。
* @return 如果没有可用的身份验证信息,则 Authentication 或 null
*/
Authentication getAuthentication();
/**
* 更改当前经过身份验证的主体,或删除身份验证信息。
* @param authentication – 新的身份验证令牌,如果不应存储进一步的身份验证信息,则为 null
*/
void setAuthentication(Authentication authentication);
}
认证对象
Authentication源码
public interface Authentication extends Principal, Serializable {
/**
* 获取用户权限
*/
Collection<? extends GrantedAuthority> getAuthorities();
/**
* 用来获取用户凭证,一般来说就是密码。
*/
Object getCredentials();
/**
* 用来获取用户的详细信息,可能是当前的请求之类。
*/
Object getDetails();
/**
* 用来获取当前用户信息信息,可能是一个用户名,也可能是一个用户对象。
*/
Object getPrincipal();
/**
* 当前用户是否认证成功。
*/
boolean isAuthenticated();
/**
*
*/
void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}
通过上述的信息,可以看出在SpringSecurity中,只要我们获取了Authentication对象,就可以获取到登录用户的用户详情了。
工具类,用于存放 SecurityContext ,默认是使用ThreadLocal实现的,这样就保证了本线程内所有的方法都可以获得SecurityContext对象。
public class SecurityContextHolder {
public static final String MODE_THREADLOCAL = "MODE_THREADLOCAL";
public static final String MODE_INHERITABLETHREADLOCAL = "MODE_INHERITABLETHREADLOCAL";
public static final String MODE_GLOBAL = "MODE_GLOBAL";
}
MODE_THREADLOCAL
MODE_INHERITABLETHREADLOCAL
MODE_GLOBAL
