Skip to content

Commit

Permalink
Merge pull request #149 from Bamdoliro/perf/#145
Browse files Browse the repository at this point in the history
[개선] JWT 에서 데이터 Claim시 서명 알고리즘의 명시적 선언 필요
  • Loading branch information
jyj1289 authored Oct 11, 2024
2 parents 7b0e055 + 3bd2e51 commit 4e0edb2
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/docs/asciidoc/auth.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ include::{snippets}/auth-controller-test/액세스_토큰으로_액세스_토큰
===== 리프레시 토큰을 보내지 않은 경우
include::{snippets}/auth-controller-test/액세스_토큰을_재발급할_때_리프레시_토큰을_보내지_않으면_에러가_발생한다/http-response.adoc[]

===== 서명 알고리즘이 불일치 하는 경우
include::{snippets}/auth-controller-test/토큰의_서명_알고리즘이_불일치하면_에러가_발생한다/http-response.adoc[]

=== 로그아웃
로그인 한 사용자는 로그아웃 할 수 있습니다.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import com.bamdoliro.maru.domain.user.service.UserFacade;
import com.bamdoliro.maru.infrastructure.persistence.auth.TokenRepository;
import com.bamdoliro.maru.shared.config.properties.JwtProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
Expand All @@ -18,7 +21,9 @@

import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Base64;
import java.util.Date;
import java.util.Map;

@RequiredArgsConstructor
@Service
Expand Down Expand Up @@ -71,6 +76,8 @@ public String getType(String token) {

private Claims extractAllClaims(String token) {
try {
validateSignatureAlgorithm(token);

return Jwts.parserBuilder()
.setSigningKey(getSigningKey(jwtProperties.getSecretKey()))
.build()
Expand All @@ -83,6 +90,19 @@ private Claims extractAllClaims(String token) {
}
}

private void validateSignatureAlgorithm(String token) throws JsonProcessingException {
String[] tokenParts = token.split("\\.");
String headerJson = new String(Base64.getDecoder().decode(tokenParts[0]));

ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> headerMap = objectMapper.readValue(headerJson, new TypeReference<>() {});
String algorithm = (String) headerMap.get("alg");

if (!algorithm.equals(SignatureAlgorithm.HS256.getValue())) {
throw new InvalidTokenException();
}
}

private Key getSigningKey(String secretKey) {
byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
return Keys.hmacShaKeyFor(keyBytes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,22 @@ class AuthControllerTest extends RestDocsTestSupport {
verify(refreshTokenUseCase, never()).execute(anyString());
}

@Test
void 토큰의_서명_알고리즘이_불일치하면_에러가_발생한다() throws Exception {
String accessToken = AuthFixture.createAccessTokenString();
doThrow(new InvalidTokenException()).when(refreshTokenUseCase).execute(accessToken);

mockMvc.perform(patch("/auth")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.header("Refresh-Token", accessToken)
)

.andExpect(status().isUnauthorized())

.andDo(restDocs.document());
}

@Test
void 유저가_로그아웃한다() throws Exception {
User user = UserFixture.createUser();
Expand Down

0 comments on commit 4e0edb2

Please sign in to comment.