์ํ๋ฆฌํฐ๋ฅผ ๋์ ํ๋ฉฐ ์ธ์ฆ, ์ธ๊ฐ์ ๊ณผ์ ์ ๋ง์ณค๋ค.
์ด์ ์ธ์ฆ ๋ฐ ์ธ๊ฐ ์์ ์์ ๋ฐ์ํ๋ ์์ธ์ ๋ํด์ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ด์ผ ํ๋๋ฐ, ํ ๊ฐ์ง ์๊ฐํด๋ด์ผ ํ๋ ๋ฌธ์ ๊ฐ ์๋ค.
์คํ๋ง ์ํ๋ฆฌํฐ๋ ํํฐ์ ๊ธฐ๋ฐํ ์ฒด์ด๋ ๊ตฌ์กฐ์ด๋ฏ๋ก, ์คํ๋ง ์ปจํ ์ด๋๊น์ง ์์ฒญ์ด ๋๋ฌํ์ง ์๋๋ค.
๋ฐ๋ผ์, @ExceptionHandler๋ฅผ ํตํ ํธํ ์์ธ ์ฒ๋ฆฌ๊ฐ ๋ถ๊ฐํ๋ค. ์ง์ Try - catch๋ก ์ก์์ ์๋ต์ ๋ด๋ ค์ฃผ๋ ๋ฐฉ๋ฒ ๋ฐ์ ์๋ค.
ํ์ง๋ง, ์คํ๋ง ์ํ๋ฆฌํฐ๊ฐ ๊ทธ๋ ๊ฒ ํ์ ํ์ง ์๋ค. ์ํ๋ฆฌํฐ ํํฐ ์ฒด์ธ์ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด ๋ง์ง๋ง ์ฆ์์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ ํํฐ๊ฐ ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ฌ๊ธฐ์ ์ฃผ๋ก ์ฌ์ฉํ๋ AuthenticationEntryPoint์ AccessDeniedHandler๋ฅผ ๊ตฌํํด ์ธ์ฆ ๋ฐ ์ธ๊ฐ ๊ณผ์ ์์ ์ผ์ด๋ ์์ธ์ ๋ํ ์๋ต์ ๋ด๋ ค์ค ์ ์๋ค.
์ธ์ฆ ๊ด๋ จ ์์ธ ์ฒ๋ฆฌ AuthenticationEntryPoint
์ธ์ฆ ๊ด๋ จ ์์ ์ ํ๋ฉฐ ์๋ง์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๊ฑฐ๋ ๋์ก๋ค.
์๋ฅผ ๋ค์ด,
- UserDetails ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ์ํด DB์์ find๋ฅผ ํ ๋์ ์์ธ - RuntimeException ๋์ง
- JWT ์ธ์ฆ ๊ณผ์ ์ค ํ ํฐ ์ ํจ์ฑ ๊ฒ์ฌ์ ์๋ง์ ์์ธ - IllegalArgumentException ๋์ง
public boolean validateAccessToken(String token) {
try {
Jwts.parserBuilder().setSigningKey(secretKey.getBytes()).build().parseClaimsJws(token);
return true;
} catch (MalformedJwtException e) {
throw new IllegalArgumentException(JwtErrorMessage.MALFORMED.getMessage());
} catch (ExpiredJwtException e) {
throw new IllegalArgumentException(JwtErrorMessage.EXPIRED.getMessage());
} catch (UnsupportedJwtException e) {
throw new IllegalArgumentException(JwtErrorMessage.UNSUPPORTED.getMessage());
} catch (ClassCastException e) {
throw new IllegalArgumentException(JwtErrorMessage.CLASS_CAST_FAIL.getMessage());
} catch (SignatureException e) {
throw new IllegalArgumentException(JwtErrorMessage.INVALID_SIGNATURE.getMessage());
} catch (Exception e) {
log.error("================================================ \n" +
"JwtValidator - validateAccessToken() ์ค๋ฅ๋ฐ์ \n" +
"token : " + token +
"\n Exception Message : " + e.getMessage() + "\n " +
"================================================");
throw new IllegalArgumentException(e.getMessage());
}
}
=> JWT ์ ํจ์ฑ ๊ฒ์ฌ์์ ์์ธ ๋์ง๊ธฐ
User dbUser = userRepository.findByLoginId(loginId).orElseThrow(() -> new UsernameNotFoundException(ResponseMessages.USER_NOT_EXISTS_MESSAGE.getMessage()));
=> UserDetails ๊ฐ์ฒด ์์ฑ ๊ณผ์ ์ค ์ฝ๋ -> ๋์ผํ๊ฒ ์์ธ๋ฅผ ๋์ง๋ค.
์ด๋ฌํ ์์ธ๋ฅผ ์ด๋์ ๊ฐ ๋ฐ์์ ์๋ต์ ๋ด๋ ค์ฃผ์ด์ผ ํ๋ค.
์ด๋, AuthenticationEntryPoint ํด๋์ค๋ฅผ ์ด์ฉํด ์์ธ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค.
@Slf4j
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
String exceptionMessage = (String) request.getAttribute("exception");
List<String> list = Arrays.stream(JwtErrorMessage.values())
.map(JwtErrorMessage::getMessage)
.collect(Collectors.toList());
if (!list.contains(exceptionMessage)) {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().print(exceptionMessage);
}
if (exceptionMessage.equals(JwtErrorMessage.MALFORMED.getMessage())) {
setResponse(response, JwtErrorMessage.MALFORMED);
} else if (exceptionMessage.equals(JwtErrorMessage.CLASS_CAST_FAIL.getMessage())) {
setResponse(response, JwtErrorMessage.CLASS_CAST_FAIL);
} else if (exceptionMessage.equals(JwtErrorMessage.EXPIRED.getMessage())) {
setResponse(response, JwtErrorMessage.EXPIRED);
} else if (exceptionMessage.equals(JwtErrorMessage.INVALID_SIGNATURE.getMessage())) {
setResponse(response, JwtErrorMessage.INVALID_SIGNATURE);
} else {
setResponse(response, JwtErrorMessage.UNSUPPORTED);
}
}
private void setResponse(HttpServletResponse response, JwtErrorMessage jwtErrorMessage) throws IOException {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().print(jwtErrorMessage.getMessage());
}
}
=> commence() ๋ฅผ ์ค๋ฒ๋ผ์ด๋ ํด ๊ตฌํํ๋ฉด ๋๋ค. ๋ ๊ฐ์ ๊ฒฝ์ฐ๋ JWT์ ๊ดํ ์์ธ ์ผ์ด์ค๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ if๋ฌธ์ผ๋ก ๋ถ๊ธฐ ์ฒ๋ฆฌํ๊ณ , ๋๋จธ์ง ์์ธ์ ๊ดํด์๋ JWT ์์ธ๋ฅผ ๋ชจ์๋ enum ํด๋์ค์ ์๋ ๊ฐ์ฒด์ธ์ง๋ฅผ ๊ฒ์ฆํ๊ณ ๋ฐ๋ก response๋ฅผ ๋ฉ์์ง์ ํจ๊ป ๋ ๋ ค์ฃผ๋ ํ์์ผ๋ก ๊ตฌํํ๋ค.
์ธ๊ฐ ๊ด๋ จ ์์ธ ์ฒ๋ฆฌ AccessDeniedHandler
์ธ์ฆ ๊ด๋ จ ์์ ์์ ์ฑ๊ณต์ ์ผ๋ก ์์ธ์ ๋ํ ์ฒ๋ฆฌ ์๋ต์ ๋ง์ณค๋ค.ํ์ง๋ง, ์ธ์ฆ์ด ์๋ฃ๋์ด๋ ์ธ๊ฐ์์ ์์ธ๊ฐ ๋ฐ์ํ๋ฉฐ ๊ทธ ์ฆ์, ๊ถํ์ด ์๋ ์๋ต๊ณผ ํจ๊ป ์ ๊ทผ์ ์ ํํด์ผ ํ๋ค. ์ด ๊ฒฝ์ฐ๋ AccessDeniedHandler ํด๋์ค๋ฅผ ๊ตฌํํ์ฌ ํด๊ฒฐํ ์ ์๋ค.
Spring Security [1] - JWT๋ฅผ ์ด์ฉํ REST API ์ธ์ฆ๊ณผ ์ธ๊ฐ
๊ธฐ์กด ์ธ์ฆ์ JWT๋ฅผ ์ด์ฉํ ํํฐ๋ก, ์ธ๊ฐ๋ ์ธํฐ์ ํฐ๋ก ์ ๋ ธํ ์ด์ ์ ์ ์ํด ์์ ๊ตฌํํ์๋ค. ์ด๋ฒ์ ๋ฆฌํฉํฐ๋ง์ ํ๋ฉด์, ์คํ๋ง์ด ์ ๊ณตํ๋ ๋ณด์ ๊ด๋ จ ํ๋ ์์ํฌ์ธ ์ํ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํด๋ณด์๋
sweeeetgoguma.tistory.com
SecurityConfig์์ ์ค์ ํ๋ฏ์ด, ๊ฐ url path๋ง๋ค role์ ์ค์ ํ ์ ์๋ค. ์ฌ๊ธฐ์ ๋ฐํ๋ ๊ถํ์ ์์ฒญ์ด ๋ค์ด์์ ๋, ํด๊ฒฐ ๊ฐ๋ฅํ๋ค.
ublic class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
setResponse(response);
}
private void setResponse(HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().print(SecurityMessage.PERMISSION_DENIED.getMessage());
}
}
=> ๋น๊ต์ ๊ฐ๋จํ๊ฒ ๊ถํ์ด ์๋ค๋ ์๋ต ๋ฉ์์ง๋ฅผ ๋ด๋ ค์ฃผ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ค.
์ด๋ ๊ฒ ์ํ๋ฆฌํฐ๋ฅผ ์ด์ฉํด ์ธ์ฆ, ์ธ๊ฐ๋ฅผ ๊ตฌํํ๋ค. ์ข ์ค๋ ๊ฑธ๋ ธ๊ณ , ์ ๋๋ก ์๊ณ ํ๋ ค๋ค ๋ณด๋ ์๊ฐ๋ ์ค๋ ๊ฑธ๋ ธ๋ค. ํ์ง๋ง ์ข์ ์์๋ถ์ด ๋์์์ด ๋ถ๋ช ํ๋ค๊ณ ์๊ฐ์ด ๋๋ค.์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์๋น์ค ๋ก์ง์ ๋ค๋ฃจ๋ฉด์ ๋ฆฌํฉํ ๋ง์ ์งํํ๋ค. ํ์ดํ ~
https://github.com/GroovyArea/My-ChickenBreast-Shop
GitHub - GroovyArea/My-ChickenBreast-Shop: shop api with spring boot
shop api with spring boot . Contribute to GroovyArea/My-ChickenBreast-Shop development by creating an account on GitHub.
github.com
'๐ Spring Framework > Spring ๊ฐ๋ ์ ๋ฆฌ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[@DataJpaTest] h2 ์ธ๋ฉ๋ชจ๋ฆฌ db๋ฅผ ์ด์ฉํ ํ ์คํธ ์ค์ ๋ฐฉ๋ฒ (0) | 2022.12.21 |
---|---|
WebFlux๋ ๋ฌด์์ด๊ณ , ์ ๋์๊ณ , ์ธ์ ์ฐ์ด๋๊ฐ? (0) | 2022.08.31 |
Spring Security [1] - JWT๋ฅผ ์ด์ฉํ REST API ์ธ์ฆ๊ณผ ์ธ๊ฐ (0) | 2022.08.18 |
2022.05.17 ใ@Transactional ์ต์ ๋ฐ ์ฑ๋ฅใ (0) | 2022.05.17 |
2022.05.13 ใSession๊ณผ Token(Jwt) & ์ธ์ฆ๊ณผ ์ธ๊ฐใ (0) | 2022.05.13 |