본문 바로가기
  • 개발하는 곰돌이

Development48

[Spring Security] 스프링 시큐리티를 적용하고 예외가 발생했을 때 403 Forbidden이 발생하는 원인과 처리 방안 목차 들어가기 전에 스프링부트 프로젝트에 스프링 시큐리티를 처음 적용해보면 여러 난관에 부딪히게 된다. 그 중 하나가 컨트롤러나 서비스 계층에서 발생한 예외의 종류에 상관없이 403 Forbidden 응답이 반환되는 것이다. 기본적으로 스프링에서는 따로 예외 처리를 하지 않았다면 예외 발생 시 500 에러가 발생한다. 그런데 스프링 시큐리티를 적용하면 메소드에서 예외가 발생했을 때 403 에러가 발생한다. 심지어 존재하지 않는 URL로 접속하여 404 Not Found가 발생해야 하는 상황에서도 403 Forbidden이 발생한다. 그 이유와 해결 방법에 대해서 정리하려고 한다. 다만 아직 스프링 시큐리티의 동작 과정을 완전히 이해하진 못했기 때문에 틀린 내용이 있을 수도 있다. 403 에러가 발생하는 .. 2023. 8. 5.
[JWT] Access Token의 한계와 Refresh Token의 필요성 [수정사항] 2023-08-20 : 자바 코드의 TokenProvider 클래스에서 리프레시 토큰이 일치하는지 검사하는 메소드가 누락된 부분 수정 목차 들어가기 전에 이전에 스프링 시큐리티와 JWT를 이용한 사용자 인증을 구현한 프로젝트에 대한 글에서 리프레시 토큰을 언급한 적이 있다. 그래서 리프레시 토큰에 대해 다뤄보면서 기존에 JWT로 사용자를 검증하던 프로젝트에 리프레시 토큰을 적용해보려고 한다. 다만 리프레시 토큰의 구현 방법에 대해 깊게 이해하고 있는 것이 아니기 때문에 틀린 내용이 있을 수 있다. Access Token? Refresh Token? 액세스 토큰은 사용자에 대한 정보를 담고 있어서 서비스에 접근(Access)할 수 있는 토큰을 의미한다. 이전 예제 프로젝트에서 사용자 검증을 위.. 2023. 7. 19.
[WebClient] Spring WebClient로 HTTPS 통신하기(sun.security.provider.certpath.SunCertPathBuilderException 해결) 목차 시작하기 전에 이전에 Spring WebClient로 HTTPS를 사용하는 웹사이트에 연결을 시도할 때 SunCertPathBuilderException이 발생하는 것을 해결하기 위해 자바에서 신뢰하는 인증서 목록에 해당 서버의 인증서를 추가하는 것으로 해결하는 글을 작성한 적이 있다. 그 당시에는 WebClient를 사용하는 방법에 익숙치 않다보니 서버마다 인증서를 추출해서 신뢰하는 인증서 목록에 추가하는 비효율적인 방법을 사용했는데, 모든 환경에서 이런 복잡한 절차 없이 WebClient를 사용한 HTTPS 통신이 가능하다는 것을 알게 되어 정리하려고 한다. 주의사항 : 이 방법은 검증 없이 모든 인증서를 신뢰하게 만들기 때문에 실제 제품에서 함부로 사용하면 안된다. 아무 설정을 하지 않은 경우.. 2023. 7. 6.
[Spring] WebClient로 외부 API를 호출하여 받은 JSON을 객체로 역직렬화할 때 대문자 필드가 바인딩되지 않는 문제 문제의 배경 기존에 WebClient로 외부 API를 호출하여 받은 JSON을 Gson 라이브러리를 통해 JsonObject로 받아서 사용하고 있던 것을 좀 더 객체지향스럽게(?) 변경하기 위해 자바 객체로 받아서 처리하도록 리팩토링하는 작업을 하고 있었다. 아래는 API의 응답으로 받는 JSON과 기존에 JSON을 JsonObject로 받아서 사용하던 코드의 일부이다. { "status": "success", "error": null, "listData": [ { "CLIENT_CODE": "123456", "DATE": "2023-06-01", "AMOUNT": 12345 }, ... ] } public Mono apiResponse(Map params) { MultiValueMap formData .. 2023. 6. 29.
[Spring Security] Spring Security 예외를 @ControllerAdvice와 @ExceptionHandler를 사용하여 전역으로 처리해보자 이 글은 이전의 [Spring Security] Spring Security와 JWT를 사용하여 사용자 인증 구현하기(Spring Boot 3.0.0 이상)에서 진행했던 예제 프로젝트에서 이어집니다. [수정사항] 2023-05-25 : 스프링 시큐리티 설정이 잘못되어 발생했던 문제의 필터 관련 내용 제거 목차 들어가기 전에 예외 처리를 해놓지 않은 예제 프로젝트 Github : Kotlin, Java 애플리케이션을 개발하다 보면 다양한 이유로 예외 처리를 하게 된다. 그중 스프링이나 스프링부트로 개발되는 경우라면 중복되는 try-catch를 줄이기 위해 @ControllerAdvice 또는 @RestControllerAdvice에서 @ExceptionHandler를 사용하여 API 호출 과정에서 발생하는.. 2023. 5. 24.
[Spring Security] Spring Security와 JWT를 사용하여 사용자 인증 구현하기(Spring Boot 3.0.0 이상) [수정사항] 스프링 시큐리티 6.1부터 SecurityFilterChain의 일부 설정들을 메소드체이닝으로 설정하는 방식이 Deprcated 되고 7부터 삭제될 예정이어서 람다를 사용한 방식으로 코드 수정 목차 시작하기 전에 글을 작성한 계기 예전에 REST API만 제공하는 백엔드 프로젝트를 진행하는 과정에서 API 사용 권한을 제한하기 위해 스프링 시큐리티와 JWT를 사용한 적이 있다. 이 때는 스프링 시큐리티와 JWT에 대한 지식이 전무해서 해당 부분은 다른 분이 작성해주신 것을 사용했다. 프로젝트 개발이 종료되고 관련 내용을 알아두는게 좋을 것 같아서 이리저리 관련 내용을 뒤적거리면서 해당 내용을 적용한 예제 프로젝트를 진행했다. 이 과정에서 진행한 과정들을 정리해보았다. 다만, 스프링 시큐리티와.. 2023. 5. 22.
[Spring Security] Spring Boot 3.0 이상에서 스프링 시큐리티 적용 시 H2 콘솔에 접속되지 않는 문제 해결 목차 문제의 상황 스프링부트 3.0.X 버전을 공부하면서 스프링 시큐리티와 JWT로 사용자 인증 기능을 설정해보기 위해 H2 DB에 사용자 정보를 저장해서 DB에 저장된 데이터를 토대로 테스트해보려고 했다. JWT를 사용했기 때문에 SessionCreationPolicy는 STATELESS로 설정했고, 로그인도 로그인 API를 호출해서 사용하기 위해 따로 formlogin() 없이 시큐리티 설정을 했다. @Configuration class SecurityConfig { private val allowedUrls = arrayOf("/", "/swagger-ui/**", "/v3/**", "/sign-up", "/sign-in", "/h2-console/**") @Bean fun filterChain(h.. 2023. 5. 19.
[WebClient] Mono에 담긴 List를 하나로 합치기 문제 상황 Spring WebClient를 통해 외부 API를 호출하는 과정에서 파라미터만 바꿔서 동일한 API를 여러 번 호출할 일이 있었다. 이 과정에서 각 API 호출 응답으로 받은 JSON을 DB에 저장하기 위해 엔티티 형태에 맞게 변경하여 엔티티의 리스트로 만들었다. 문제는 모든 API 호출을 비동기로 진행했기 때문에 실제 반환값은 엔티티의 리스트가 담긴 Mono 객체였다. 평범한 리스트였다면 그냥 List.addAll()을 통해 합칠 수 있겠지만 Mono 객체라서 불가능했다. 해결 방법 그렇게 방법을 찾던 중에 Stack Overflow에서 방법을 찾았다. Mono의 flatMapMany()와 Flux의 fromIterable()을 사용하면 Mono 객체를 Flux 객체로 변환할 수 있다. M.. 2023. 5. 14.