java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringSecurity获取当前登录用户的信息

SpringSecurity获取当前登录用户的信息的几种方法实现

作者:代码代码快快显灵

本文主要介绍了SpringSecurity中获取当前登录用户信息的多种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在 Spring Security 中,当前登录用户的信息实际上都存储在与当前线程绑定的 SecurityContext 中,里面保存了一个 Authentication 对象。你展示的这几种写法,其实都是不同的方式来获取这个 Authentication 对象或者从中提取出用户信息。下面详细说明每种方式的原理和适用场景:

1. 直接注入 Principal

@GetMapping("/welcome")
@ResponseBody
public Object toLoginInfo(Principal principal){
    return principal;
}

说明:

当你在 Controller 方法中直接声明一个 Principal 类型的参数时,Spring Security 会自动注入当前登录用户对应的 Principal 对象。通常,Principal 只包含最基本的用户标识(例如用户名),但如果需要更多信息,就需要使用 Authentication

2. 直接注入 Authentication

@GetMapping("/welcome2")
@ResponseBody
public Object toLoginInfo2(Authentication authentication) {
    return authentication;
}

说明:Authentication 接口继承自 Principal,除了包含用户名外,还包含了用户的权限信息(Authorities)、认证凭证(Credentials)、认证状态等。直接注入 Authentication 可以获取更丰富的信息,是实际开发中常用的方式之一。

3. 注入 UsernamePasswordAuthenticationToken

@GetMapping("/welcome3")
@ResponseBody
public Object toLoginInfo3(UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) {
    return usernamePasswordAuthenticationToken;
}

4. 通过 SecurityContextHolder 获取

@GetMapping("/welcome4")
@ResponseBody
public Object toLoginInfo4() {
    return SecurityContextHolder.getContext().getAuthentication();
}

说明:这种方式是从静态的 SecurityContextHolder 中获取当前线程绑定的 SecurityContext,再从中取出 Authentication 对象。使用这种方式可以在非 Controller 的地方(例如在业务逻辑或工具类中)获取当前登录用户的信息。

5. 使用自定义工具方法

@GetMapping("/welcome5")
@ResponseBody
public Object toLoginInfo5() {
    return LoginInfoUtil.getCurrentLoginUser();
}

说明:这是一个对上面几种方式的封装,通常会在项目中封装一个工具类(如 LoginInfoUtil),内部封装对 SecurityContextHolder 的调用或者其他逻辑处理,返回一个更为友好的用户信息对象。这样做有利于集中管理和统一用户信息的获取逻辑。

LoginInfoUtil:

public class LoginInfoUtil {

    /**
     * 获取当前登录用户信息
     * @return
     */
    public static TUser getCurrentLoginUser() {
        return  (TUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    }
}

总结

Authentication 继承自 Principal,这意味着它不仅包含基本的身份信息,还扩展了额外的认证细节。

UsernamePasswordAuthenticationToken 是 Authentication 接口的一个具体实现,专门用于用户名和密码认证的场景。

在实际认证流程中,通常会通过 UsernamePasswordAuthenticationToken 来封装用户提交的认证信息,并在认证成功后返回一个完整的认证对象。

如何获取更多的用户信息

实体类实现UserDetails接口,实现UserDetails的7个接口,这样,你既可以保留 Spring Security 要求的七个方法,又可以在实体类中扩展其他的业务属性。

自定义用户实体类

扩展业务属性:在你的用户实体类中,可以添加额外的属性,例如真实姓名、邮箱、电话等等。

实现 UserDetails 接口的七个方法:

之后由于之前是返回UserDetails的实现类User,此时由于我们有自定义的实现类TUser,因此我们可以直接返回了,不需要使用框架的User类了。

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 通过用户名查询数据库
     TUser user =  userMapper.selectByLoginAct(username);
     if (user == null){
         throw new UsernameNotFoundException("用户不存在");
     }
     return user; // 实现了UserDetails接口,包含所有字段

//     // 返回框架User(UserDetails的实现类)但是使用UserDetails接收
//      return  User.builder()
//                .username(user.getLoginAct())
//                .password(user.getLoginPwd())
//                .authorities(AuthorityUtils.NO_AUTHORITIES) // 没有权限(权限管理部分)
//                .build(); // 把UserDetails(User)返回给框架之后,框架会采用密码加密器进行密码的比较
    }

如何忽略某些字段(不返回前端)以及规范日期格式

使用

@JsonIgnore // 表示该字段不返回给前端

如果实体类当中日期类较多,每一个字段加上规范会很麻烦,因此一般会在application.yml当中配置Jackson的转换方式:

spring:
  application:
    name: Security-04-login-info

# jackson配置 时间格式(使用指定的时区和格式)
  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss

登录成功后的处理:

 @Bean// 安全过滤器链Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception { //httpSecurity方法参数注入Bean
        return httpSecurity
                // 配置自己的登录页面
                .formLogin( (formLogin) ->{
                    formLogin.loginProcessingUrl("/login") // 登录账户密码往哪个地址提交
                            .loginPage("/toLogin")// 定制登录页面
                            .successForwardUrl("/welcome"); // 登录成功之后,跳转到哪个页面,默认是跳转到之前的页面
                })
                .authorizeHttpRequests((authorizeHttpRequests)->{
                    authorizeHttpRequests
                            .requestMatchers("/toLogin","/common/captcha").permitAll() // 特殊情况,toLogin不需要登录就可以访问, 验证码不需要登录就可以访问
                            .anyRequest().authenticated(); // 除了上述特殊情况之外,其他任何请求都需要认证之后才能访问
                })
                .addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class)
                .build();
    }

使用 .successForwardUrl("/welcome") 时,Spring Security 在用户登录成功后不会发起新的 HTTP 请求,而是通过内部的请求转发(forward)的方式,将当前请求转发到指定的 URL(即 "/welcome")。这意味着:

总结来说,.successForwardUrl("/welcome") 用于在认证成功后,将请求内部转发到 "/welcome" 接口,从而执行相应的处理逻辑,而不是向浏览器发起新的请求。

到此这篇关于SpringSecurity获取当前登录用户的信息的文章就介绍到这了,更多相关SpringSecurity获取当前登录用户的信息内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文