Spring Security使用详解11(获取当前用户的用户名、id)

有时我们需要获取当前登录的用户信息(比如用户名),通常有如下几种方式来实现。

方法1:通过 Authentication.getPrincipal() 获取用户信息

(1)通过 Authentication.getPrincipal() 可以获取到代表当前用户的信息,这个对象通常是 UserDetails 的实例。通过 UserDetails 的实例我们可以获取到当前用户的用户名、密码、角色等信息。

Spring Security 使用一个 Authentication 对象来描述当前用户的相关信息,而 SecurityContext 持有的是代表当前用户相关信息的 Authentication 的引用。

这个 Authentication 对象不需要我们自己去创建,在与系统交互的过程中,Spring Security 会自动为我们创建相应的 Authentication 对象,然后赋值给当前的 SecurityContext。

1@RestController 2public class HelloController { 3 4 @GetMapping("/hello") 5 public String hello() { 6 Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 7 8 if (principal instanceof UserDetails) { 9 return ((UserDetails) principal).get.getUsername(); 10 } 11 12 if (principal instanceof Principal) { 13 return ((Principal) principal).getName(); 14 } 15 16 return "当前登录用户:" + String.valueOf(principal); 17 } 18}

 

(2)由于获取当前用户的用户名是一种比较常见的需求,其实 Spring Security 在 Authentication 中的实现类中已经为我们做了相关实现,所以获取当前用户的用户名有如下更简单的方式:

1@RestController 2public class HelloController { 3 4 @GetMapping("/hello") 5 public String hello() { 6 return "当前登录用户:" + SecurityContextHolder.getContext().getAuthentication().getName(); 7 } 8}

方法2:通过注入 Principal 接口获取用户信息

在运行过程中,Spring 会将 Username、Password、Authentication、Token 注入到 Principal 接口中,我们可以直接获取使用:

1@RestController 2public class HelloController { 3 4 @GetMapping("/hello") 5 public String hello(Principal principal) { 6 // 注意:如果未登录,principal 为 null 7 return "当前登录用户:" + principal.getName(); 8 } 9}

附:获取登录用户的 id 等其他信息

(1)如果我们是基于数据库的用户角色配置的话,那么会创建用户表对应的实体类,同时用户实体类需要实现 UserDetails 接口。

关于基于数据库的用户角色配置认证更详细的用法,可以参考我之前显得文章:

Spring Security使用详解3(基于数据库的用户角色配置)

1@NoArgsConstructor 2@ToString 3public class User implements UserDetails { 4 private Integer id; 5 private String username; 6 private String password; 7 private Boolean enabled; 8 private Boolean locked; 9 private List<Role> roles; 10 11 @Override 12 public Collection<? extends GrantedAuthority> getAuthorities() { 13 List<SimpleGrantedAuthority> authorities = new ArrayList<>(); 14 for (Role role : roles) { 15 authorities.add(new SimpleGrantedAuthority(role.getName())); 16 } 17 return authorities; 18 } 19 20 @Override 21 public String getPassword() { 22 return password; 23 } 24 25 @Override 26 public String getUsername() { 27 return username; 28 } 29 30 @Override 31 public boolean isAccountNonExpired() { 32 return true; 33 } 34 35 @Override 36 public boolean isAccountNonLocked() { 37 return !locked; 38 } 39 40 @Override 41 public boolean isCredentialsNonExpired() { 42 return true; 43 } 44 45 @Override 46 public boolean isEnabled() { 47 return enabled; 48 } 49 50 /** get、set 方法 **/ 51 52 public Integer getId() { 53 return id; 54 } 55 56 public void setId(Integer id) { 57 this.id = id; 58 } 59 60 public void setUsername(String username) { 61 this.username = username; 62 } 63 64 public void setPassword(String password) { 65 this.password = password; 66 } 67 68 public void setEnabled(Boolean enabled) { 69 this.enabled = enabled; 70 } 71 72 public Boolean getLocked() { 73 return locked; 74 } 75 76 public void setLocked(Boolean locked) { 77 this.locked = locked; 78 } 79 80 public List<Role> getRoles() { 81 return roles; 82 } 83 84 public void setRoles(List<Role> roles) { 85 this.roles = roles; 86 } 87}

 (2)我们同样通过 Authentication.getPrincipal() 可以获取当前登录用户的 UserDetails 实例,然后再转换成自定义的用户实体类 User,这样便能获取用户的 ID 等信息:

1@RestController 2public class HelloController { 3 4 @GetMapping("/hello") 5 public String hello() { 6 Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 7 User user = (User)principal; 8 return "当前登录用户信息:" + user.toString(); 9 } 10}

(3)运行结果如下:

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang

Java日期时间API系列31

  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前