简体   繁体   中英

Spring boot create a custom annotation to get logged in user?

I have a entity model called User . I have implemented UserDetailsService and used it in WebSecurityConfig like this. Removed unnecessary code for brevity.

@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();
    }
}

Now at any place during a request-response, I can use this code to get the currently logged in user

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

Now my question is, is there any way to create a custom AOP or annotation that gives me access to logged in user so that I can use it anywhere like in my controller as shown below?

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

So like in the above example, can I create an annotation @CurrentUser that gives me currently logged in user(if not throws an exception, which I can catch in controller advice)?

Note: How I get the user is up to me. In the above example I am using authentcation.getName() and then querying my db to build User entity. But I can use any other way to do so. I just want to create an annotation like CurrentUser and then add the code (of retrieving the user) behind it.

Add the following bean:

(change UserDetail if you are using a different entity for the principal).

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

Then set-up the @CurrentUser annotation as followed:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM