JwtAuthenticationFilter 인증 필터 내 검증되는 부분은 두 종류가 존재한다.
1. ID 존재 여부
2. 비밀번호 일치 여부
두 종류의 검증에 대해 거절 상황 시 하나의 로직으로 응답할 수 있는 방법이 필요하였다....
인증처리 시 Exception 처리 부분을 먼저 확인해본다.
인증 처리하는 Filter 일부분
1. Authentication authenticationResult = attemptAuthentication(request, response);
attemptAuthentication 메소드를 통하여 ID, 패스워드 등 인증한다.
이 때, ID 및 비밀번호 검증 실패 시 AuthenticationException 을 던지게 된다.
2.catch (AuthenticationException ex)
3. unsuccessfulAuthentication(request, response, ex);
AuthenticationException catch하여 반드시 unsuccessfulAuthentication 메소드를 반드시 실행된다.
또한 다음 필터는 수행하지 않은 채 지나쳐온 필터들로 돌아가 각 필터들의 후처리를 진행한다.
Exception발생 시 타는 로직을 보고 아래와 같이 생각이 들었다.
아! unsuccessfulAuthentication은 반드시 타니 여기서 처리해야겠다!!
또! 다음 필터를 수행하지않고 수행되었던 필터들로 돌아가니 앞단에 Exception을 처리하는 필터를 만들어 여기서 Exception을 캐치하여 처리해야겠다!!
방법 1. unsuccessfulAuthentication 오버라이딩
AuthenticationException을 던지게 되면 unsuccessfulAuthentication 메소드로 반드시 들어올 수 밖에 없게 된다.
따라서 아이디 검증 실패 시 AuthenticationException throw , 비밀번호 검증 실패 시 AuthenticationException throrw 하기만 한다면 해당 메소드에서 공통으로 응답 처리할 수 있다!!!
CustomAuthenticationProvider
아이디 및 비밀번호 검증 진행
@Slf4j
@RequiredArgsConstructor
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final MemberService memberService;
private final PasswordEncoder bCryptPasswordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String id = authentication.getPrincipal().toString();
String pwd = authentication.getCredentials().toString();
//1. ID 존재 여부 확인 -> 없는 경우 AuthenticationException 상속받은 커스터마이징Excception 던짐
UserDetails ud= memberService.loadUserByUsername(id);
//2. 비밀번호 일치 여부 확인 ->-> 일치하지 않는 경우 AuthenticationException 상속받은 커스터마이징Excception 던짐
checkPassword(pwd,ud.getPassword());
Collection<? extends GrantedAuthority> authorities = ud.getAuthorities();
return new UsernamePasswordAuthenticationToken(ud,pwd,authorities);
}
.......
}
JwtAuthenticationFilter
Exception발생 시 catch하여 처리하는 unsuccessfulAuthentication
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
ObjectMapper om = new ObjectMapper();
ResultResDto resultResDto= ResultResDto.builder()
.msg(((CustomLoginException)e).getResultcode().getMsg())
.code(((CustomLoginException)e).getResultcode().getResultCode())
.build();
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
om.writeValue(response.getOutputStream(),resultResDto);
}
AuthenticationException을 상속받은 커스텀Exception
@Slf4j
@Getter
public class CustomLoginException extends AuthenticationException {
public RESULTCODE resultcode;
public CustomLoginException(RESULTCODE resultcode){
super(resultcode.getMsg());
log.error(resultcode.getMsg());
this.resultcode=resultcode;
}
}
/* ID 조회실패 */
public class MemberNotFoundException extends CustomLoginException{
public MemberNotFoundException(RESULTCODE resultcode){
super(resultcode);
}
}
/* 비밀번호 불일치 */
public class PassWordMisMatchException extends CustomLoginException{
public PassWordMisMatchException(RESULTCODE resultcode){
super(resultcode);
}
}
결과
case1) 아이디가 존재하지 않는 경우
case2) 비밀번호가 일치하지 않는 경우
방법 2. 커스터마이징한 Exception 처리를 할 수 있는 Filter 구현
다음필터들을 실행시키는 게 아닌 실행되었던 필터들에 대하여 후처리를 진행하기에
커스텀Exception처리할 수 있는 필터를 앞단에 배치시키고,
해당 필터에서 후처리로 커스텀 익셉션 cath하고 공통응답하도록 구현할 수 있다.
'SpringBoot > SpringSecurity' 카테고리의 다른 글
리소스 접근 시 인증,인가 Exception 처리 (0) | 2023.10.19 |
---|---|
[이슈] AuthenticationProvider 인터페이스 구현 후 적용되지 않는 상황 처리 (0) | 2023.10.19 |