SpringBoot - 安全管理框架Spring Security使用详解11(获取当前用户的用户名、id)
有时我们需要获取当前登录的用户信息(比如用户名),通常有如下几种方式来实现。
(2)由于获取当前用户的用户名是一种比较常见的需求,其实 Spring Security 在 Authentication 中的实现类中已经为我们做了相关实现,所以获取当前用户的用户名有如下更简单的方式:
(2)我们同样通过 Authentication.getPrincipal() 可以获取当前登录用户的 UserDetails 实例,然后再转换成自定义的用户实体类 User,这样便能获取用户的 ID 等信息:
(3)运行结果如下:
方法1:通过 Authentication.getPrincipal() 获取用户信息
(1)通过 Authentication.getPrincipal() 可以获取到代表当前用户的信息,这个对象通常是 UserDetails 的实例。通过 UserDetails 的实例我们可以获取到当前用户的用户名、密码、角色等信息。 Spring Security 使用一个 Authentication 对象来描述当前用户的相关信息,而 SecurityContext 持有的是代表当前用户相关信息的 Authentication 的引用。
这个 Authentication 对象不需要我们自己去创建,在与系统交互的过程中,Spring Security 会自动为我们创建相应的 Authentication 对象,然后赋值给当前的 SecurityContext。
这个 Authentication 对象不需要我们自己去创建,在与系统交互的过程中,Spring Security 会自动为我们创建相应的 Authentication 对象,然后赋值给当前的 SecurityContext。
@RestController public class HelloController { @GetMapping("/hello") public String hello() { Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (principal instanceof UserDetails) { return ((UserDetails) principal).get.getUsername(); } if (principal instanceof Principal) { return ((Principal) principal).getName(); } return "当前登录用户:" + String.valueOf(principal); } }

(2)由于获取当前用户的用户名是一种比较常见的需求,其实 Spring Security 在 Authentication 中的实现类中已经为我们做了相关实现,所以获取当前用户的用户名有如下更简单的方式:
@RestController public class HelloController { @GetMapping("/hello") public String hello() { return "当前登录用户:" + SecurityContextHolder.getContext().getAuthentication().getName(); } }
方法2:通过注入 Principal 接口获取用户信息
在运行过程中,Spring 会将 Username、Password、Authentication、Token 注入到 Principal 接口中,我们可以直接获取使用:@RestController public class HelloController { @GetMapping("/hello") public String hello(Principal principal) { // 注意:如果未登录,principal 为 null return "当前登录用户:" + principal.getName(); } }
附:获取登录用户的 id 等其他信息
(1)如果我们是基于数据库的用户角色配置的话,那么会创建用户表对应的实体类,同时用户实体类需要实现 UserDetails 接口。
关于基于数据库的用户角色配置认证更详细的用法,可以参考我之前显得文章:
@NoArgsConstructor @ToString public class User implements UserDetails { private Integer id; private String username; private String password; private Boolean enabled; private Boolean locked; private List<Role> roles; @Override public Collection<? extends GrantedAuthority> getAuthorities() { List<SimpleGrantedAuthority> authorities = new ArrayList<>(); for (Role role : roles) { authorities.add(new SimpleGrantedAuthority(role.getName())); } return authorities; } @Override public String getPassword() { return password; } @Override public String getUsername() { return username; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return !locked; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return enabled; } /** get、set 方法 **/ public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public void setEnabled(Boolean enabled) { this.enabled = enabled; } public Boolean getLocked() { return locked; } public void setLocked(Boolean locked) { this.locked = locked; } public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } }
(2)我们同样通过 Authentication.getPrincipal() 可以获取当前登录用户的 UserDetails 实例,然后再转换成自定义的用户实体类 User,这样便能获取用户的 ID 等信息:
@RestController public class HelloController { @GetMapping("/hello") public String hello() { Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); User user = (User)principal; return "当前登录用户信息:" + user.toString(); } }
(3)运行结果如下:
