programing

Spring boot - 로그인 후 사용자 객체 반환

iphone6s 2023. 7. 31. 21:11
반응형

Spring boot - 로그인 후 사용자 객체 반환

WebSecurityConfigurerAdapter가 다음과 같이 구성된 스프링 부팅 애플리케이션이 있습니다.

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);

인증에 성공한 후 인증된 사용자에 대한 세부 정보가 포함된 사용자 지정 개체를 반환하는 자체 컨트롤러와 같은 것을 추가할 수 있습니까?

업데이트: 명확하게 하기 위해, 저는 각도가 있는 애플리케이션을 클라이언트로 사용하고 있습니다.현재 저는 제 클라이언트로부터 서버에 2가지 요청을 해야 합니다. 1. 인증을 위해 /login URL에 POST 요청을 해야 합니다. 2. 인증된 사용자 데이터를 검색하기 위해 GET 요청을 받아야 합니다.

나의 목표는 2dn 요청을 하지 않아도 되도록 첫 번째 요청을 나에게 사용자 정보를 돌려주는 것입니다.현재 첫 번째 요청은 사용자만 인증하고 서버에 세션을 만든 후 데이터 없이 '200 OK' 상태 응답을 보냅니다.로그인한 사용자에 대한 데이터가 포함된 성공 응답을 반환하기를 원합니다.

응답:

정답은 댓글에 있으므로 여기에 적겠습니다. successHandler에서 컨트롤러로 리디렉션하여 현재 로그인된 사용자 정보를 반환해야 했습니다(이 경우 컨트롤러는 url '/user/me'에 있음).

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

당신의 문제를 제대로 이해한다면 다음 방법을 제안할 수 있습니다.

우선 사용자 정보를 포함하는 클래스를 구현해야 합니다.이 클래스는 다음에서 상속되어야 합니다.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
}

다음 단계에서는 사용자가 직접 인터페이스를 구현해야 합니다.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;
    }

}

보시다시피 이 클래스에는 사용자 지정 사용자 세부 정보를 로드하고 설정할 수 있는 방법이 하나만 있습니다.참고로, 이 수업은 다음과 같이 표시했습니다.@Service주석그러나 Java-config 또는 XML 컨텍스트에서 등록할 수 있습니다.

이제 인증에 성공한 후 사용자 데이터에 액세스하려면 Spring이 컨트롤러의 메서드에서 주체를 자동으로 전달하는 다음 접근 방식을 사용할 수 있습니다.

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

또는 다른 한 가지 방법:

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

이 방법은 스프링이 주체를 자동으로 통과하지 않는 다른 위치에서 사용할 수 있습니다.

인증확인 후 사용할 수 있는 특정 주소로 이동하려면SimpleUrlAuthenticationSuccessHandler구성에서 생성하기만 하면 됩니다.

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

구성에서 사용할 수 있습니다.

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

그런 다음 컨트롤러를 생성하면 지정된 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
     }

}

응답도 할 수 ("JSON"을 사용합니다).@ResponseBody주석) 또는 기타 항목은 프런트엔드에 따라 다릅니다.이것이 도움이 되기를 바랍니다.

수락된 답변에서 원하는 데이터를 얻으려면 두 번의 통화가 필요합니다.사용자 지정 Ajax Authentication에서 로그인한 후 데이터를 반환하기만 하면 됩니다.SuccessHandler는 이렇게 합니다.

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

    };
}

성공 처리자를 등록합니다.

http.successHandler(ajaxAuthenticationSuccessHandler())

언급URL : https://stackoverflow.com/questions/35241182/spring-boot-return-user-object-after-log-in

반응형