1

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.

theprogrammer
  • 1,698
  • 7
  • 28
  • 48
  • search https://stackoverflow.com/questions/10247116/spring-aop-pointcut-for-annotated-argument and there are multiple ways of retrieving user information https://www.baeldung.com/get-user-in-spring-security – Toerktumlare Jan 31 '20 at 21:38
  • To whomsoever downvoted the question, could you please let me know what's the reason? Is this approach dangerous with regards to security or has some serious performance implications? Or did I frame the question badly? If so let me know so I can improve these questions from next time. – theprogrammer Feb 04 '20 at 02:48
  • @ThomasAndolf Yes I know how to retrieve the user. I am looking to create an easy to use annotation for that. and thanks will look into that aop link – theprogrammer Feb 04 '20 at 02:48

1 Answers1

0

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 {}

Bluurr
  • 457
  • 5
  • 6