From 900edb5c37d17fc581a340eae519552de9ef0fc2 Mon Sep 17 00:00:00 2001 From: ay-eonii Date: Sat, 18 Nov 2023 19:23:37 +0900 Subject: [PATCH 1/4] =?UTF-8?q?RAC-128=20feat:=20=EC=9D=B8=EC=A6=9D=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=ED=95=B8=EB=93=A4=EB=9F=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../contant/AuthResponseCode.java | 3 +- .../contant/AuthResponseMessage.java | 3 +- .../CustomAuthenticationEntryPoint.java | 35 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/postgraduate/global/config/security/filter/CustomAuthenticationEntryPoint.java diff --git a/src/main/java/com/postgraduate/domain/auth/presentation/contant/AuthResponseCode.java b/src/main/java/com/postgraduate/domain/auth/presentation/contant/AuthResponseCode.java index 6b9f8202..5c61276d 100644 --- a/src/main/java/com/postgraduate/domain/auth/presentation/contant/AuthResponseCode.java +++ b/src/main/java/com/postgraduate/domain/auth/presentation/contant/AuthResponseCode.java @@ -15,6 +15,7 @@ public enum AuthResponseCode { AUTH_DENIED("EX900"), AUTH_INVALID_KAKAO("EX901"), - AUTH_KAKAO_CODE("EX902"); + AUTH_KAKAO_CODE("EX902"), + AUTH_FAILED("EX903"); private final String code; } diff --git a/src/main/java/com/postgraduate/domain/auth/presentation/contant/AuthResponseMessage.java b/src/main/java/com/postgraduate/domain/auth/presentation/contant/AuthResponseMessage.java index 1f7efbcb..cda4bafa 100644 --- a/src/main/java/com/postgraduate/domain/auth/presentation/contant/AuthResponseMessage.java +++ b/src/main/java/com/postgraduate/domain/auth/presentation/contant/AuthResponseMessage.java @@ -12,6 +12,7 @@ public enum AuthResponseMessage { PERMISSION_DENIED("권한이 없습니다."), KAKAO_INVALID("카카오 정보가 유효하지 않습니다."), - KAKAO_CODE("카카오 코드가 유효하지 않습니다."); + KAKAO_CODE("카카오 코드가 유효하지 않습니다."), + FAILED_AUTH("사용자 인증에 실패했습니다."); private final String message; } diff --git a/src/main/java/com/postgraduate/global/config/security/filter/CustomAuthenticationEntryPoint.java b/src/main/java/com/postgraduate/global/config/security/filter/CustomAuthenticationEntryPoint.java new file mode 100644 index 00000000..751b7879 --- /dev/null +++ b/src/main/java/com/postgraduate/global/config/security/filter/CustomAuthenticationEntryPoint.java @@ -0,0 +1,35 @@ +package com.postgraduate.global.config.security.filter; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.postgraduate.global.dto.ErrorResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +import static com.postgraduate.domain.auth.presentation.contant.AuthResponseCode.AUTH_FAILED; +import static com.postgraduate.domain.auth.presentation.contant.AuthResponseMessage.FAILED_AUTH; + +@Component +@RequiredArgsConstructor +public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { + private final ObjectMapper objectMapper; + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.setCharacterEncoding("UTF-8"); + objectMapper.writeValue( + response.getOutputStream(), + new ErrorResponse(AUTH_FAILED.getCode(), FAILED_AUTH.getMessage()) + ); + } +} From 59a5a8b0c34714f667d8b15bb9cb5bde01f129db Mon Sep 17 00:00:00 2001 From: ay-eonii Date: Sat, 18 Nov 2023 19:23:51 +0900 Subject: [PATCH 2/4] =?UTF-8?q?RAC-128=20feat:=20=EC=9D=B8=EA=B0=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=ED=95=B8=EB=93=A4=EB=9F=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filter/CustomAccessDeniedHandler.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/main/java/com/postgraduate/global/config/security/filter/CustomAccessDeniedHandler.java diff --git a/src/main/java/com/postgraduate/global/config/security/filter/CustomAccessDeniedHandler.java b/src/main/java/com/postgraduate/global/config/security/filter/CustomAccessDeniedHandler.java new file mode 100644 index 00000000..15417edf --- /dev/null +++ b/src/main/java/com/postgraduate/global/config/security/filter/CustomAccessDeniedHandler.java @@ -0,0 +1,32 @@ +package com.postgraduate.global.config.security.filter; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.postgraduate.global.dto.ErrorResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +import static com.postgraduate.domain.auth.presentation.contant.AuthResponseCode.AUTH_DENIED; +import static com.postgraduate.domain.auth.presentation.contant.AuthResponseMessage.PERMISSION_DENIED; + +@Component +@RequiredArgsConstructor +public class CustomAccessDeniedHandler implements AccessDeniedHandler { + private final ObjectMapper objectMapper; + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException { + response.setStatus(HttpStatus.FORBIDDEN.value()); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + objectMapper.writeValue( + response.getOutputStream(), + new ErrorResponse(AUTH_DENIED.getCode(), PERMISSION_DENIED.getMessage()) + ); + } +} From a1f61cfb9228436fee7fc89b2dd4970cf99eae7a Mon Sep 17 00:00:00 2001 From: ay-eonii Date: Sat, 18 Nov 2023 19:24:23 +0900 Subject: [PATCH 3/4] =?UTF-8?q?RAC-128=20feat:=20`SecurityConfig`=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/security/SecurityConfig.java | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/postgraduate/global/config/security/SecurityConfig.java b/src/main/java/com/postgraduate/global/config/security/SecurityConfig.java index 0487c7bd..e2ec972e 100644 --- a/src/main/java/com/postgraduate/global/config/security/SecurityConfig.java +++ b/src/main/java/com/postgraduate/global/config/security/SecurityConfig.java @@ -1,6 +1,8 @@ package com.postgraduate.global.config.security; import com.postgraduate.domain.user.domain.entity.constant.Role; +import com.postgraduate.global.config.security.filter.CustomAccessDeniedHandler; +import com.postgraduate.global.config.security.filter.CustomAuthenticationEntryPoint; import com.postgraduate.global.config.security.jwt.JwtFilter; import com.postgraduate.global.config.security.jwt.JwtProvider; import lombok.RequiredArgsConstructor; @@ -21,8 +23,10 @@ @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfig { - private final JwtProvider jwtProvider; private static final String[] PASS = {"/resource/**", "/css/**", "/js/**", "/img/**", "/lib/**"}; + private final JwtProvider jwtProvider; + private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint; + private final CustomAccessDeniedHandler customAccessDeniedHandler; @Bean public BCryptPasswordEncoder encodePassword() { return new BCryptPasswordEncoder(); @@ -31,15 +35,15 @@ public BCryptPasswordEncoder encodePassword() { @Bean protected SecurityFilterChain config(HttpSecurity http) throws Exception { http - .csrf(csrf->csrf.disable()) + .csrf(csrf -> csrf.disable()) .cors(corsConfigurer -> corsConfigurer.configurationSource(source()) ) - .httpBasic(httpBasic->httpBasic.disable()) + .httpBasic(httpBasic -> httpBasic.disable()) .headers((headers) -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)); http - .formLogin(formLogin->formLogin.disable()) - .logout(logout->logout.disable()); + .formLogin(formLogin -> formLogin.disable()) + .logout(logout -> logout.disable()); http .authorizeHttpRequests((authorize) -> authorize .requestMatchers(PASS).permitAll() @@ -48,15 +52,8 @@ protected SecurityFilterChain config(HttpSecurity http) throws Exception { ) .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .exceptionHandling((exceptions) -> exceptions - .authenticationEntryPoint((request, response, authException) -> { - //TODO: 인증되지 않은 유저 예외 - throw new IllegalAccessError("실패"); - }) - .accessDeniedHandler((request, response, authException) -> { - //TODO: 엑세스 거부 예외 - throw new IllegalAccessError("실패"); - - }) + .authenticationEntryPoint(customAuthenticationEntryPoint) + .accessDeniedHandler(customAccessDeniedHandler) ) .addFilterBefore(new JwtFilter(jwtProvider), UsernamePasswordAuthenticationFilter.class); From 6a713f8fb3cb71a63c0643b9a22dee5e760f8f4b Mon Sep 17 00:00:00 2001 From: ay-eonii Date: Sat, 18 Nov 2023 19:30:28 +0900 Subject: [PATCH 4/4] =?UTF-8?q?RAC-128=20feat:=20response=20encoding=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/security/filter/CustomAccessDeniedHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/postgraduate/global/config/security/filter/CustomAccessDeniedHandler.java b/src/main/java/com/postgraduate/global/config/security/filter/CustomAccessDeniedHandler.java index 15417edf..6e0b5f9b 100644 --- a/src/main/java/com/postgraduate/global/config/security/filter/CustomAccessDeniedHandler.java +++ b/src/main/java/com/postgraduate/global/config/security/filter/CustomAccessDeniedHandler.java @@ -24,6 +24,7 @@ public class CustomAccessDeniedHandler implements AccessDeniedHandler { public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException { response.setStatus(HttpStatus.FORBIDDEN.value()); response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.setCharacterEncoding("UTF-8"); objectMapper.writeValue( response.getOutputStream(), new ErrorResponse(AUTH_DENIED.getCode(), PERMISSION_DENIED.getMessage())