-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
82 changed files
with
2,419 additions
and
565 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
src/main/java/com/depromeet/domain/auth/application/IdTokenVerifier.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.depromeet.domain.auth.application; | ||
|
||
import com.depromeet.domain.auth.domain.OauthProvider; | ||
import com.depromeet.global.error.exception.CustomException; | ||
import com.depromeet.global.error.exception.ErrorCode; | ||
import com.depromeet.infra.config.oidc.OidcProperties; | ||
import java.util.List; | ||
import java.util.Map; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.security.oauth2.core.oidc.OidcIdToken; | ||
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; | ||
import org.springframework.security.oauth2.core.oidc.user.OidcUser; | ||
import org.springframework.security.oauth2.jwt.Jwt; | ||
import org.springframework.security.oauth2.jwt.JwtDecoder; | ||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class IdTokenVerifier { | ||
|
||
private final OidcProperties oidcProperties; | ||
private final Map<OauthProvider, JwtDecoder> decoders = | ||
Map.of( | ||
OauthProvider.KAKAO, buildDecoder(OauthProvider.KAKAO.getJwkSetUrl()), | ||
OauthProvider.APPLE, buildDecoder(OauthProvider.APPLE.getJwkSetUrl())); | ||
|
||
private JwtDecoder buildDecoder(String jwkUrl) { | ||
return NimbusJwtDecoder.withJwkSetUri(jwkUrl).build(); | ||
} | ||
|
||
public OidcUser getOidcUser(String idToken, OauthProvider provider) { | ||
Jwt jwt = getJwt(idToken, provider); | ||
OidcIdToken oidcIdToken = getOidcIdToken(jwt); | ||
|
||
validateIssuer(oidcIdToken, provider.getIssuer()); | ||
validateAudience(oidcIdToken, oidcProperties.getAudiences(provider)); | ||
validateNonce(oidcIdToken, provider); | ||
|
||
return new DefaultOidcUser(null, oidcIdToken); | ||
} | ||
|
||
private Jwt getJwt(String idToken, OauthProvider provider) { | ||
return decoders.get(provider).decode(idToken); | ||
} | ||
|
||
private void validateAudience(OidcIdToken oidcIdToken, List<String> targetAudiences) { | ||
String idTokenAudience = oidcIdToken.getAudience().get(0); | ||
|
||
if (idTokenAudience == null || !targetAudiences.contains(idTokenAudience)) { | ||
throw new CustomException(ErrorCode.ID_TOKEN_VERIFICATION_FAILED); | ||
} | ||
} | ||
|
||
private void validateIssuer(OidcIdToken oidcIdToken, String targetIssuer) { | ||
String idTokenIssuer = oidcIdToken.getIssuer().toString(); | ||
|
||
if (idTokenIssuer == null || !idTokenIssuer.equals(targetIssuer)) { | ||
throw new CustomException(ErrorCode.ID_TOKEN_VERIFICATION_FAILED); | ||
} | ||
} | ||
|
||
private OidcIdToken getOidcIdToken(Jwt jwt) { | ||
return new OidcIdToken( | ||
jwt.getTokenValue(), jwt.getIssuedAt(), jwt.getExpiresAt(), jwt.getClaims()); | ||
} | ||
|
||
private void validateNonce(OidcIdToken idToken, OauthProvider provider) { | ||
// TODO: 랜덤 nonce 사용하도록 개선 | ||
String idTokenNonce = idToken.getNonce(); | ||
String targetNonce = oidcProperties.nonce(); | ||
|
||
// 카카오, 애플 앱 토큰의 경우 라이브러리 문제로 nonce 검증 생략 | ||
if (isKakaoAppToken(idToken, provider) || isAppleAppToken(idToken, provider)) { | ||
return; | ||
} | ||
|
||
if (idTokenNonce == null || !idTokenNonce.equals(targetNonce)) { | ||
throw new CustomException(ErrorCode.ID_TOKEN_VERIFICATION_FAILED); | ||
} | ||
} | ||
|
||
private boolean isKakaoAppToken(OidcIdToken idToken, OauthProvider provider) { | ||
return provider == OauthProvider.KAKAO | ||
&& idToken.getAudience().contains(oidcProperties.getKakaoAppAudience()); | ||
} | ||
|
||
private boolean isAppleAppToken(OidcIdToken idToken, OauthProvider provider) { | ||
return provider == OauthProvider.APPLE | ||
&& idToken.getAudience().contains(oidcProperties.getAppleAppAudience()); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/com/depromeet/domain/auth/application/nickname/AnimalNicknameGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.depromeet.domain.auth.application.nickname; | ||
|
||
import com.depromeet.global.common.constants.NicknameGenerationConstants; | ||
import java.util.concurrent.ThreadLocalRandom; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class AnimalNicknameGenerator implements NicknameGenerationStrategy { | ||
|
||
@Override | ||
public String generate() { | ||
int animalIndex = | ||
ThreadLocalRandom.current() | ||
.nextInt(NicknameGenerationConstants.ANIMAL_NAMES.length); | ||
int prefixIndex = | ||
ThreadLocalRandom.current() | ||
.nextInt(NicknameGenerationConstants.PREFIX_NAMES.length); | ||
|
||
String animalName = NicknameGenerationConstants.ANIMAL_NAMES[animalIndex]; | ||
String prefix = NicknameGenerationConstants.PREFIX_NAMES[prefixIndex]; | ||
|
||
return prefix + animalName; | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
src/main/java/com/depromeet/domain/auth/application/nickname/NicknameGenerationStrategy.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.depromeet.domain.auth.application.nickname; | ||
|
||
public interface NicknameGenerationStrategy { | ||
String generate(); | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/com/depromeet/domain/auth/domain/OauthProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.depromeet.domain.auth.domain; | ||
|
||
import static com.depromeet.global.common.constants.SecurityConstants.*; | ||
|
||
import com.depromeet.global.error.exception.CustomException; | ||
import com.depromeet.global.error.exception.ErrorCode; | ||
import java.util.Arrays; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public enum OauthProvider { | ||
KAKAO(KAKAO_JWK_SET_URL, KAKAO_ISSUER), | ||
APPLE(APPLE_JWK_SET_URL, APPLE_ISSUER), | ||
; | ||
|
||
private final String jwkSetUrl; | ||
private final String issuer; | ||
|
||
public static OauthProvider of(String issuer) { | ||
return Arrays.stream(values()) | ||
.filter(oauthProvider -> oauthProvider.issuer.equals(issuer)) | ||
.findFirst() | ||
.orElseThrow(() -> new CustomException(ErrorCode.OAUTH_PROVIDER_NOT_FOUND)); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/com/depromeet/domain/auth/dto/request/IdTokenRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.depromeet.domain.auth.dto.request; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import jakarta.validation.constraints.NotNull; | ||
|
||
public record IdTokenRequest( | ||
@NotNull(message = "Id Token은 비워둘 수 없습니다.") @Schema(description = "Id Token") | ||
String idToken) {} |
14 changes: 14 additions & 0 deletions
14
src/main/java/com/depromeet/domain/auth/dto/response/SocialLoginResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.depromeet.domain.auth.dto.response; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
|
||
public record SocialLoginResponse( | ||
@Schema(description = "엑세스 토큰", defaultValue = "accessToken") String accessToken, | ||
@Schema(description = "리프레시 토큰", defaultValue = "refreshToken") String refreshToken, | ||
@Schema(description = "게스트 여부", defaultValue = "true") boolean isGuest) { | ||
|
||
public static SocialLoginResponse from(TokenPairResponse tokenPairResponse, boolean isGuest) { | ||
return new SocialLoginResponse( | ||
tokenPairResponse.accessToken(), tokenPairResponse.refreshToken(), isGuest); | ||
} | ||
} |
Oops, something went wrong.