로그인 후 처리

귀찮Lee·2022년 9월 3일
0

Spring Security

목록 보기
11/13

◎ Spring Security에서 구조

  • AuthenicationFailureHandler

    • 로그인에 실패했을 때, 처리하는 Class
    • 해당 Interface를 구현하고 Spring Container에 넣어준다면, 후처리를 직접 할 수 있다.
  • AuthenicationSuccessHandler

    • 로그인에 성공했을 때, 처리하는 Class
    • 해당 Interface를 구현하고 Spring Container에 넣어준다면, 후처리를 직접 할 수 있다.

◎ 로그인 후 처리 예시

  • 직접 사용해보았던 후처리 방법을 소개

    @Configuration
    @AllArgsConstructor
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
    public class SecurityConfig {
    
        private final CustomAuthFailureHandler customAuthFailureHandler;
    
        @Bean
        public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    
            http.
                ...
                    .and().formLogin().loginProcessingUrl("/api/login")
                    .defaultSuccessUrl("/auth/success", true)
                    // 성공 후 처리는 Handler가 아닌 SecurityConfig에서 설정함
                    // true로 설정하지 않으면 인증 권한에 한번 막힌 후에 로그인 시,
                    // 인증 권한이 막혔던 url로 리다이렉트함
                    .failureHandler(customAuthFailureHandler)
                    // 실패 후 처리는 customAuthFailureHandler를 통해 실시
                    ...
    
            return http.build();
        }
    
        ...
    
    }
    • AuthenticationFailureHandler
    @Component
    public class CustomAuthFailureHandler extends SimpleUrlAuthenticationFailureHandler {
    
        @Override
        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                            AuthenticationException exception) throws IOException, ServletException {
    
            String errorMessage;
            if (exception instanceof BadCredentialsException) {
                errorMessage = "Email or Password id Not Matched";
            } else if (exception instanceof UsernameNotFoundException) {
                errorMessage = "Account is not Exist";
            } else if (exception instanceof InternalAuthenticationServiceException) {
                errorMessage = "Account is not Exist";
            } else if (exception instanceof AuthenticationCredentialsNotFoundException) {
                errorMessage = "Authentication is Denied";
            } else {
                errorMessage = "Sorry, Developer's mistake. Just send Email To Developer";
            }
    
            errorMessage = URLEncoder.encode(errorMessage, "UTF-8");
            setDefaultFailureUrl("/auth/fail?message="+errorMessage);
            super.onAuthenticationFailure(request, response, exception);
        }
    }
    • 리다이렉트 처리
    @Controller
    @RequestMapping("/auth")
    @RequiredArgsConstructor
    public class SecurityController {
    
        private final MemberMapper memberMapper;
    
        @GetMapping("/fail")
        public ResponseEntity loginFail(@RequestParam String message){
    
            return new ResponseEntity(
                    new Response(400, message), HttpStatus.BAD_REQUEST
            );
        }
    
        @GetMapping("/success")
        public String successLogin() {
    
            return "redirect:/auth/info";
        }
    
        @Secured("ROLE_USER")
        @GetMapping("/info")
        public ResponseEntity returnLoginInfo(Authentication authentication){
            if (authentication == null) throw new BusinessLogicException(ExceptionCode.MEMBER_NOT_FOUND);
            PrincipalDetails userDetails = (PrincipalDetails) authentication.getPrincipal();
            Member member = userDetails.getMember();
    
            MemberDto.Response response = memberMapper.memberToMemberResponseDto(member);
            return new ResponseEntity(
                    new SingleResponseDto<>(response), HttpStatus.OK
            );
        }
    
    }

◎ 참고 자료

profile
배운 것은 기록하자! / 오류 지적은 언제나 환영!

0개의 댓글