Spring boot - return user object after log in

前端 未结 2 1333
栀梦
栀梦 2021-01-31 11:35

I have a spring boot application with WebSecurityConfigurerAdapter configured like this -

http.csrf().disable()
                    .exceptionHandling()
                


        
相关标签:
2条回答
  • In the accepted answer you need two calls to get the data you want. Simply return the data after the login in 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 the successhandler:

    http.successHandler(ajaxAuthenticationSuccessHandler())
    
    0 讨论(0)
  • 2021-01-31 12:27

    If I understand your problem right, I can suggest next way.

    First of all you have to implement class, that will contain user information. This class must 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
    }
    

    Next step, you have create you own implementation of interface org.springframework.security.core.userdetails.UserDetailsService:

    @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's data from DB or from 
            //any other source and do:
            //userDetails.setFirstName(firstName);
            //userDetails.setLastName(lastName);
    
            return userDetails;
        }
    
    }
    

    As you see, this class has just one method, where you can load and set custom user details. Note, that I marked this class with @Service annotation. But you can register it in your Java-config or XML context.

    Now, to access your user data after successful authentication, you can use next approach, when Spring will automatically pass principal in controller's 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 one 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 pass principal automatically.

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

    @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 controller, that will send response from speciafied 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
         }
    
    }
    

    Of cause, you can return not only view, but JSON response (using @ResponseBody annotation), or something else, depends on you front-end. Hope this will be helpful.

    0 讨论(0)
提交回复
热议问题