diff --git a/src/main/java/com/tune_fun/v1/account/application/service/oauth2/decorator/OAuth2AuthorizationCodeGrantRequestEntityDecorator.java b/src/main/java/com/tune_fun/v1/account/application/service/oauth2/decorator/OAuth2AuthorizationCodeGrantRequestEntityDecorator.java index 7c23d6a6..a774278d 100644 --- a/src/main/java/com/tune_fun/v1/account/application/service/oauth2/decorator/OAuth2AuthorizationCodeGrantRequestEntityDecorator.java +++ b/src/main/java/com/tune_fun/v1/account/application/service/oauth2/decorator/OAuth2AuthorizationCodeGrantRequestEntityDecorator.java @@ -1,5 +1,6 @@ package com.tune_fun.v1.account.application.service.oauth2.decorator; +import com.tune_fun.v1.common.helper.AppleOAuth2ClientSecretHelper; import com.tune_fun.v1.common.property.AppleProperty; import com.tune_fun.v1.common.util.EncryptUtil; import io.jsonwebtoken.Jwts; @@ -27,8 +28,7 @@ @RequiredArgsConstructor public class OAuth2AuthorizationCodeGrantRequestEntityDecorator extends OAuth2AuthorizationCodeGrantRequestEntityConverter { - private final AppleProperty appleProperty; - private final OAuth2ClientProperties oAuth2ClientProperties; + private final AppleOAuth2ClientSecretHelper appleOAuth2ClientSecretHelper; @Override @@ -51,7 +51,7 @@ public RequestEntity convert(@NotNull OAuth2AuthorizationCodeGrantRequest req String clientSecret; try { - clientSecret = createAppleClientSecret(); + clientSecret = appleOAuth2ClientSecretHelper.createAppleClientSecret(); } catch (IOException e) { throw new IllegalStateException("Error while creating Apple client secret."); } @@ -61,23 +61,4 @@ public RequestEntity convert(@NotNull OAuth2AuthorizationCodeGrantRequest req return new RequestEntity<>(params, entity.getHeaders(), entity.getMethod(), entity.getUrl()); } - private String createAppleClientSecret() throws IOException { - Instant expirationInstant = Instant.now().plusSeconds(30 * 24 * 60 * 60); // 30 days in seconds - final StringReader appleOAuth2KeyReader = new StringReader(appleProperty.oauth2Key()); - final PrivateKey appleOAuth2PrivateKey = EncryptUtil.parsePemAndGetPrivateKey(appleOAuth2KeyReader); - - - return Jwts.builder() - .header().add("kid", appleProperty.keyId()) - .and() - .issuer(appleProperty.teamId()) - .issuedAt(Date.from(Instant.now())) - .expiration(Date.from(expirationInstant)) - .audience().add("https://appleid.apple.com") - .and() - .subject(oAuth2ClientProperties.getRegistration().get(APPLE.getRegistrationId()).getClientId()) - .signWith(appleOAuth2PrivateKey, Jwts.SIG.ES256) - .compact(); - } - } diff --git a/src/main/java/com/tune_fun/v1/account/application/service/oauth2/handler/OAuth2AuthenticationSuccessHandler.java b/src/main/java/com/tune_fun/v1/account/application/service/oauth2/handler/OAuth2AuthenticationSuccessHandler.java index 4d0bdb14..7c7981f2 100644 --- a/src/main/java/com/tune_fun/v1/account/application/service/oauth2/handler/OAuth2AuthenticationSuccessHandler.java +++ b/src/main/java/com/tune_fun/v1/account/application/service/oauth2/handler/OAuth2AuthenticationSuccessHandler.java @@ -14,12 +14,14 @@ import com.tune_fun.v1.account.domain.state.oauth2.*; import com.tune_fun.v1.common.exception.CommonApplicationException; import com.tune_fun.v1.common.exception.OAuth2AuthenticationProcessingException; +import com.tune_fun.v1.common.helper.AppleOAuth2ClientSecretHelper; import com.tune_fun.v1.common.hexagon.UseCase; import com.tune_fun.v1.common.util.StringUtil; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties; @@ -67,6 +69,8 @@ public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationS private final RevokeOAuth2GooglePort revokeOAuth2GooglePort; private final RevokeOAuth2ApplePort revokeOAuth2ApplePort; + private final AppleOAuth2ClientSecretHelper appleOAuth2ClientSecretHelper; + private static final Function AUTH_FAILED_URL_FUNCTION = targetUrl -> fromUriString(targetUrl).queryParam("error", "Authorization failed") .build().toUriString(); @@ -86,6 +90,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo getRedirectStrategy().sendRedirect(request, response, targetUrl); } + @SneakyThrows @Transactional public String determineTargetUrl(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { @@ -147,7 +152,7 @@ private String createJwtTokenAndRedirectUri(final OAuth2UserPrincipal principal, } @Transactional - public String unlink(final OAuth2UserPrincipal principal, final String targetUrl, HttpServletRequest request) { + public String unlink(final OAuth2UserPrincipal principal, final String targetUrl, HttpServletRequest request) throws IOException { Optional usernameOptional = getCookie(request, USERNAME_PARAM_COOKIE_NAME).map(Cookie::getValue); if (usernameOptional.isEmpty()) return AUTH_FAILED_URL_FUNCTION.apply(targetUrl); @@ -208,7 +213,7 @@ public void saveOAuth2Account(final OAuth2UserPrincipal principal, final Account saveOAuth2AccountPort.saveOAuth2Account(saveOAuth2AccountBehavior); } - private void unlinkHttpRequest(final OAuth2Provider provider, final String accessToken) { + private void unlinkHttpRequest(final OAuth2Provider provider, final String accessToken) throws IOException { if (accessToken == null || accessToken.trim().isEmpty()) throw new OAuth2AuthenticationProcessingException("Access token must not be null or empty"); @@ -224,14 +229,14 @@ private void unlinkHttpRequest(final OAuth2Provider provider, final String acces } @NotNull - private RevokeOAuth2AppleRequest getRevokeOAuth2AppleRequest(final String accessToken) { + private RevokeOAuth2AppleRequest getRevokeOAuth2AppleRequest(final String accessToken) throws IOException { OAuth2ClientProperties.Registration registration = oAuth2ClientProperties .getRegistration() .get(APPLE.getRegistrationId()); if (registration == null) throw new OAuth2AuthenticationProcessingException("Apple registration not found"); - return new RevokeOAuth2AppleRequest(registration.getClientId(), registration.getClientSecret(), accessToken); + return new RevokeOAuth2AppleRequest(registration.getClientId(), appleOAuth2ClientSecretHelper.createAppleClientSecret(), accessToken); } } diff --git a/src/main/java/com/tune_fun/v1/common/helper/AppleOAuth2ClientSecretHelper.java b/src/main/java/com/tune_fun/v1/common/helper/AppleOAuth2ClientSecretHelper.java new file mode 100644 index 00000000..6c87b747 --- /dev/null +++ b/src/main/java/com/tune_fun/v1/common/helper/AppleOAuth2ClientSecretHelper.java @@ -0,0 +1,44 @@ +package com.tune_fun.v1.common.helper; + +import com.tune_fun.v1.common.property.AppleProperty; +import com.tune_fun.v1.common.util.EncryptUtil; +import io.jsonwebtoken.Jwts; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.io.StringReader; +import java.security.PrivateKey; +import java.time.Instant; +import java.util.Date; + +import static com.tune_fun.v1.account.domain.state.oauth2.OAuth2Provider.APPLE; + +@Component +@RequiredArgsConstructor +public class AppleOAuth2ClientSecretHelper { + + private final AppleProperty appleProperty; + private final OAuth2ClientProperties oAuth2ClientProperties; + + public String createAppleClientSecret() throws IOException { + Instant expirationInstant = Instant.now().plusSeconds(30 * 24 * 60 * 60); // 30 days in seconds + final StringReader appleOAuth2KeyReader = new StringReader(appleProperty.oauth2Key()); + final PrivateKey appleOAuth2PrivateKey = EncryptUtil.parsePemAndGetPrivateKey(appleOAuth2KeyReader); + + + return Jwts.builder() + .header().add("kid", appleProperty.keyId()) + .and() + .issuer(appleProperty.teamId()) + .issuedAt(Date.from(Instant.now())) + .expiration(Date.from(expirationInstant)) + .audience().add("https://appleid.apple.com") + .and() + .subject(oAuth2ClientProperties.getRegistration().get(APPLE.getRegistrationId()).getClientId()) + .signWith(appleOAuth2PrivateKey, Jwts.SIG.ES256) + .compact(); + } + +}