Spring boot - return user object after login

I have a spring boot application with a WebSecurityConfigurerAdapter configured as follows:

http.csrf().disable() .exceptionHandling() .authenticationEntryPoint(restAuthenticationEntryPoint) .and() .authorizeRequests() .antMatchers("/user/*", "/habbit/*").authenticated() .and() .formLogin() .loginProcessingUrl("/login") .permitAll() .usernameParameter("email") .passwordParameter("pass") .successHandler(authenticationSuccessHandler) .failureHandler(new SimpleUrlAuthenticationFailureHandler()) .and() .logout() .logoutUrl("/logout") .invalidateHttpSession(true); 

Can I add something like my own controller, which after successful authentication would return a user object with some information about the authenticated user?

Update: For clarity, I am using the angular application as a client. Currently, I need to make 2 requests from my client to the server: 1. POST request to / login URL for authentication. 2. GET request to receive authenticated user data.

My goal is to return the 1st request to me with user information, so I do not need to make a 2dn request. Currently, the first request only authenticates the user, creates a session on the server and sends a “200 OK” response with no data . I want it to return a successful response with data about the registered user.

Answer:

The correct answer is in the comments, so I will write it here: I had to redirect from my successHandler to my controller, which, in turn, returns the current user information (in my case, the controller is in url '/ user / me':

  @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { clearAuthenticationAttributes(request); getRedirectStrategy().sendRedirect(request, response, "/user/me"); } 
+5
source share
2 answers

If I understand your problem correctly, I can suggest the following way.

First of all, you need to implement a class that will contain information about the user. This class should be inherited from org.springframework.security.core.userdetails.User :

 public class CustomUserDetails extends User { public CustomUserDetails(String username, String password, Collection<? extends GrantedAuthority> authorities) { super(username, password, authorities); } //for example lets add some person data private String firstName; private String lastName; //getters and setters } 

In the next step, you created your own implementation of the org.springframework.security.core.userdetails.UserDetailsService interface:

 @Service public class CustomUserDetailService implements UserDetailsService{ @Override public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException{ if(StringUtils.isEmpty(userName)) throw new UsernameNotFoundException("User name is empty"); //if you don't use authority based security, just add empty set Set<GrantedAuthority> authorities = new HashSet<>(); CustomUserDetails userDetails = new CustomUserDetails(userName, "", authorities); //here you can load user data from DB or from //any other source and do: //userDetails.setFirstName(firstName); //userDetails.setLastName(lastName); return userDetails; } } 

As you can see, this class has only one method in which you can load and configure user user data. Note that I marked this class with the @Service annotation. But you can register it in your Java-config or XML context.

Now, in order to access your user data after successful authentication, you can use the following approach when Spring automatically passes the principal in the controller method:

 @Controller public class MyController{ @RequestMapping("/mapping") public String myMethod(Principal principal, ModelMap model){ CustomUserDetails userDetails = (CustomUserDetails)principal; model.addAttribute("firstName", userDetails.getFirstName()); model.addAttribute("lastName", userDetails.getLastName()); } } 

Or another way:

 @Controller public class MyController{ @RequestMapping("/mapping") public String myMethod(ModelMap model){ Authentication auth = SecurityContextHolder.getContext().getAuthentication(); CustomUserDetails userDetails = (CustomUserDetails)auth.getPrincipal(); model.addAttribute("firstName", userDetails.getFirstName()); model.addAttribute("lastName", userDetails.getLastName()); } } 

This method can be used in other places where Spring does not automatically convey basic information.

To go to a specific address after successful authentication, you can use SimpleUrlAuthenticationSuccessHandler . Just create it in your configuration:

 @Bean public SavedRequestAwareAuthenticationSuccessHandler successHandler() { SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); successHandler.setTargetUrlParameter("/succeslogin"); return successHandler; } 

and use it in your configuration:

 http.formLogin() .loginProcessingUrl("/login") .permitAll() .usernameParameter("email") .passwordParameter("pass") .successHandler(successHandler()) 

after that you can create a controller that will send a response from a special URL:

 @Controller @RequestMapping("/sucesslogin") public class SuccessLoginController{ @RequestMapping(method = RequestMethod.POST) public String index(ModelMap model, Principal principal){ //here you can return view with response } } 

Because of this, you can return not only the view, but also the JSON response (using the @ResponseBody annotation) or something else, it is up to you. Hope this will be helpful.

+7
source

In the accepted answer, you need two calls to get the data you need. Just return the data after logging into a custom AjaxAuthenticationSuccessHandler like this.

 @Bean public AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler() { return new AjaxAuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { response.getWriter().write(new ObjectMapper().writeValueAsString(new UserAuthenticationResponse(authentication.getName(), 123l))); response.setStatus(200); } }; } 

and register a success handler:

 http.successHandler(ajaxAuthenticationSuccessHandler()) 
+1
source

Source: https://habr.com/ru/post/1242437/


All Articles