首页 > 解决方案 > Spring Boot 创建自定义注释以获取登录用户?

问题描述

我有一个名为User. 我已经UserDetailsService像这样在 WebSecurityConfig 中实现并使用了它。为简洁起见,删除了不必要的代码。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

现在在请求响应期间的任何地方,我都可以使用此代码获取当前登录的用户

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();
// now use some jpa logic to retrive User entity using above username

现在我的问题是,有什么方法可以创建自定义 AOP 或注释,让我可以访问已登录的用户,以便我可以在控制器中的任何地方使用它,如下所示?

public class LoginController {
    public String response(@CurrentUser User user) {
        // do logic once you have access to logged in user with help of @CurrentUser annotation
    }
}

所以就像上面的例子一样,我可以创建一个注释@CurrentUser来给我当前登录的用户(如果没有抛出异常,我可以在控制器建议中捕获)?

注意:我如何获得用户取决于我。在上面的示例中,我使用 authentcation.getName() 然后查询我的数据库来构建用户实体。但我可以使用任何其他方式来做到这一点。我只想创建一个像 CurrentUser 这样的注释,然后在它后面添加代码(检索用户)。

标签: javaspring-bootspring-securityannotationsannotation-processing

解决方案


添加以下bean:

UserDetail如果您为委托人使用不同的实体,请更改)。

  @Bean
  public Function<UserDetails, User> fetchUser() {
    return (principal -> {
      String name = principal.getUsername()
      //do JPA logic
      return ...
    });
  }

然后设置@CurrentUser注释如下:

@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@AuthenticationPrincipal(expression = "@fetchUser.apply(#this)", errorOnInvalidType=true)
public @interface CurrentUser {}


推荐阅读