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

Stella981
• 阅读 1220

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

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

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

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

这个 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);
    }
}

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

(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 接口。

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

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

@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)运行结果如下:

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

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
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
Wesley13 Wesley13
2年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
kenx kenx
2年前
SpringBoot @ModelAttribute 用法
前言项目中遇到这么一个使用场景,用户的登录信息给予token保存,在需要有登录信息的地方,每次都要去获取用户Id,但每次在请求方法中去获取用户信息,代码重复,冗余,很low于是想到了用@ModelAttribute这个属性使用场景不用@ModelAttribute时候在需要用户信息的请求中每次需要单独获取用户信息JavaStringtoken
易娃 易娃
3年前
Android开发 - 获取Android设备的唯一标识码(Android 6.0或更高)
在我们的APP开发中,通常需要获取到设备的唯一标识。在Android6.0之前,有很多方法我们可以方便获取到硬件的唯一标识,但是在Android6.0之后,Android系统大幅限制了我们获取设备的硬件信息。Android6.0之前的方法(已过时)1.DEVICE\_ID通getSystem
Wesley13 Wesley13
2年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Stella981 Stella981
2年前
CAS 实现站内单点登录及实现第三方 OAuth、OpenId 登录(三)
一、概括    在大多数情况下,随着用户登录系统后,用户ID、用户名、Email、用户头像等等基本信息,需要被使用直到用户退出系统。    CASServer默认情况下,成功登录后,只会返回用户标示(通常是用户名)给CASClient。这时,各个Client还需要根据用户标示,去查询用户其它信息,这时如果如果CASSer
Wesley13 Wesley13
2年前
Java日期时间API系列23
  有时候,往往需要统计某个时间区间的销量等问题,这就需要准确的起始时间,获取准确开始时间00:00:00,获取准确结束时间23:59:59。下面增加了一一些方法,获取当天起始时间,昨天起始时间,当前月第一天开始时间,当前月最后一天结束时间,上个月第一天开始时间,上个月最后一天结束时间,某个指定月的起始结束时间等等。其中月份最后一天往往因为月份不同和
Wesley13 Wesley13
2年前
unity将 -u4E00 这种 编码 转汉字 方法
 unity中直接使用 JsonMapper.ToJson(对象),取到的字符串,里面汉字可能是\\u4E00类似这种其实也不用转,服务器会通过类似fastjson发序列化的方式,将json转对象,获取对象的值就是中文但是有时服务器要求将传参中字符串中类似\\u4E00这种转汉字,就需要下面 publ