-
Spring Security + JWT ํ์๊ฐ์ , ๋ก๊ทธ์ธ (3)Spring 2022. 10. 23. 17:11๋ฐ์ํ
๐ก ์ง๋ ํฌ์คํธ์ ์ด์ด์ Security์ 403 Forbidden ์๋ฌ๋ฅผ ํธ๋ค๋ง ํ๋ Class๋ฅผ
์ค์ ํด๋ณด๊ฒ ์ต๋๋ค.
์ด์ ํฌ์คํ ์ ํด๋น ๋งํฌ๋ฅผ ์ฐธ์กฐ ํด์ฃผ์๊ธธ ๋ฐ๋๋๋ค.
https://developer-been.tistory.com/3Spring Security
AccessDeniedHandler์ธํฐํ์ด์ค์ AuthenticationEntryPoint์ธํฐํ์ด์ค๊ฐ ์กด์ฌํฉ๋๋ค.
๐ก AccessDeniedHandler
์๋ฒ์ ์์ฒญ์ ํ ๋ ์ก์ธ์ค๊ฐ ๊ฐ๋ฅํ์ง ๊ถํ์ ์ฒดํฌํ ์ก์ธ์ค ํ ์ ์๋ ์์ฒญ์ ํ์์ ๋์ ๋ฉ๋๋ค.
๐ก AuthenticationEntryPoint
์ธ์ฆ ๋์ง์์ ์ ์ ๊ฐ ์์ฒญ์ ํ์๋ ๋์ ๋ฉ๋๋ค.๐ก ๊ตฌํํ๋ ์ด์ ?
ํ์ฌ Filter๋ฅผ ์ฌ์ฉํ์ฌ Servlet๋จ์์ ๊ฒ์ฆ์ ํ๊ณ ์๋๋ฐ, ์ด ๋
1๏ธโฃ ๊ถํ์ด ์๋ ์ก์ธ์ค ์์ฒญ 2๏ธโฃ ์ธ์ฆ์ด ๋์ง ์์ ์์ฒญ
๋ ๊ฐ์ง ๊ฒฝ์ฐ ๋ชจ๋ 403 forbidden ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ด ๊ฒฝ์ฐ์ DispatcherServlet๋จ๊น์ง ๋ฟ์ ์๊ฐ ์๊ณ , Servlet๋จ์์ ์ข ๋ฃ๊ฐ ๋ฉ๋๋ค.
์ด๋ฐ ์ํฉ์ ์ฌ์ฉ์ ์ ์ ์๋ฌ ํธ๋ค๋ง์ ํ๊ธฐ ์ํด์ ์ฌ์ฉํฉ๋๋ค.๐ก ์ฌ์ฉ๋ฐฉ๋ฒ
(1)๋ฒ ๊ธ์์ WebSecurityConfig์ ์ค์ ํ ๋๋ก ํด๋์ค๋ค์ ๋ช ์ ํด์ค์ผ ํฉ๋๋ค..and() .exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint) .accessDeniedHandler(customAccessDeniedHandler)
๐ CustomAccessDeniedHandler Calss ์์ฑ
@Component @Slf4j public class CustomAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException { log.error("Forbidden : ์ ๊ทผ ๊ถํ์ด ์์ต๋๋ค."); httpServletResponse.setContentType("application/json; charset=UTF-8"); httpServletResponse.setStatus(HttpStatus.OK.value()); try (OutputStream os = httpServletResponse.getOutputStream()){ BaseResDto baseResDto = new BaseResDto(); baseResDto.setResultCode(ResultCode.ACCESS_NO_AUTH.getResultCode()); baseResDto.setResultMessage(ResultCode.ACCESS_NO_AUTH.getResultMessage()); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.writeValue(os, baseResDto); os.flush(); } } }
- 403 forbidden ์๋ฌ (AccessDeniedException) ๋ฐ์์, AccessDeniedHandler๋ฅผ ๊ตฌํํ ํด๋น Customํด๋์ค๋ก ์ง์ ์ ํฉ๋๋ค.
- ์ฌ์ฉ์ ์ ์ ํด๋์ค๋ฅผ ๋ด๋ ค์ฃผ๊ธฐ ์ํด์ json type, status code 200์ผ๋ก ์ค์ ์ ํด์ค๋๋ค.
- ์ฌ์ฉ์ ์ ์ ํด๋์ค๋ฅผ ์์ฑํ๊ณ , ์ฌ์ฉ์ ์ ์ ์๋ฌ ๋ฉ์์ง๋ฅผ Set ํฉ๋๋ค.
- ObjectMapper๋ฅผ ์ด์ฉํ์ฌ writeํ๊ณ flush ํ๋ฉด Status 200 ์ฝ๋์ ํจ๊ป ์ฌ์ฉ์ ์ ์ ํด๋์ค๋ฅผ Json ํํ๋ก ์ถ๋ ฅํ ์ ์์ต๋๋ค.
๐ CustomAuthenticationEntryPoint Calss ์์ฑ
๐ก Jwt ๊ฒ์ฆ์ ๋ฐ์ํ๋ Exception์ ์ฒ๋ฆฌํด์ฃผ๊ธฐ ์ํด AuthenticationEntryPoint๋ฅผ ๊ตฌํํ EntryPoint ์ ๋๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก 403 forbidden Error๊ฐ ๋ฐ์ํ๊ณ , Servlet๋จ์์ ์ข ๋ฃ๋๊ธฐ ๋๋ฌธ์
์ฌ์ฉ์ ์ ์ ์๋ฌ ํธ๋ค๋ง์ ํ๊ธฐ ์ํด์ ์ฌ์ฉํฉ๋๋ค.@Component public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { BaseResDto baseResDto = new BaseResDto(); String exceptionType = (String) request.getAttribute("exception"); if (exceptionType.equals("invalidSignature")) { baseResDto.setResultCode(ResultCode.SIGNATURE_EXCEPTION.getResultCode()); baseResDto.setResultMessage(ResultCode.SIGNATURE_EXCEPTION.getResultMessage()); } else if (exceptionType.equals("invalidJwt")) { baseResDto.setResultCode(ResultCode.MALFORMED_JWT_EXCEPTION.getResultCode()); baseResDto.setResultMessage(ResultCode.MALFORMED_JWT_EXCEPTION.getResultMessage()); } else if (exceptionType.equals("expiredJwt")) { baseResDto.setResultCode(ResultCode.ACCESS_TOKEN_EXPIRED.getResultCode()); baseResDto.setResultMessage(ResultCode.ACCESS_TOKEN_EXPIRED.getResultMessage()); } else if (exceptionType.equals("claimsEmpty")) { baseResDto.setResultCode(ResultCode.ILLEGAL_ARGUMENT_EXCEPTION.getResultCode()); baseResDto.setResultMessage(ResultCode.ILLEGAL_ARGUMENT_EXCEPTION.getResultMessage()); } else { baseResDto.setResultCode(ResultCode.UNSUPPORTED_JWT_EXCEPTION.getResultCode()); baseResDto.setResultMessage(ResultCode.UNSUPPORTED_JWT_EXCEPTION.getResultMessage()); } JSONObject jsonObject = new JSONObject(); jsonObject.put("resultCode", baseResDto.getResultCode()); jsonObject.put("resultMessage", baseResDto.getResultMessage()); response.setStatus(HttpStatus.OK.value()); response.setContentType("application/json;charset=UTF-8"); response.getWriter().print(jsonObject); response.getWriter().flush(); } }
์์ ๊ตฌํํ JwtTokenProvider.class์ validateToken() ํจ์์์ Jwt ๊ด๋ จ Exception์ ๋ถ๊ธฐ ์ฒ๋ฆฌ ํ์ต๋๋ค.
๊ณผ์ ์ ์๋์ ๊ฐ์ต๋๋ค.
1๏ธโฃ ๊ฐ Exception๋ง๋ค HttpServletRequest์ Attribute๋ฅผ set ํด์ค ์ํ์์, EntryPoint๋ก ๋์ด์ต๋๋ค.
2๏ธโฃ EntryPoint์์ Attribute๋ฅผ get ํด์ ์ฌ์ฉ์ ์ ์ String์ ํ์ธ ํ ํ์, ํด๋น Exception์ ๋ง๋ ์ฌ์ฉ์ ์ ์ ํด๋์ค๋ฅผ Set ํด์ค๋๋ค.
3๏ธโฃ JSONObject์ ์ฌ์ฉ์ ์ ์ ํด๋์ค๋ฅผ Put ํ ๋ค, HttpServletResponse์ json type๊ณผ status 200 Code๋ฅผ Set ํฉ๋๋ค.
4๏ธโฃ HttpServletResponse์ getWriter().print() ๋ฉ์๋๋ฅผ ์ด์ฉํด json ๋ฌธ์์ด์ ์ถ๋ ฅํ๊ณ , ์ต์ข ์ ์ผ๋ก flush()๋ฅผ ํตํด ๋น์์ค๋๋ค.์ด๋ ๊ฒ 403 forbidden ์๋ฌ๋ฅผ ํธ๋ค๋ง ํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ดค์ต๋๋ค.
Servlet๋จ์์ ์ข ๋ฃ๋๋ฒ๋ฆฌ๋ ์๋ฌ๋๋ฌธ์ ์ฌ์ฉ์ ์ ์ ๋ฉ์์ง๋ฅผ ๋ด๋ ค์ค ์ ์์๋
์ฌ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ด ๋๊ฒ ์ต๋๋ค.๋ฐ์ํ'Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] Spring์์ CORS ์ฒ๋ฆฌ(์ค์ )ํ๋ ๋ฐฉ๋ฒ (0) 2022.10.27 [Spring] Spring์์ Scheduler ์ฒ๋ฆฌํ๊ธฐ (0) 2022.10.26 Spring Boot ๊ณตํต Global Exception Handler (0) 2022.10.23 Spring Security + JWT ํ์๊ฐ์ , ๋ก๊ทธ์ธ (2) (0) 2022.10.23 Spring Security + JWT ํ์๊ฐ์ , ๋ก๊ทธ์ธ (1) (0) 2022.10.23