-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[PEAUTY-19] Impl social sign in (#3)
* PEAUTY-19 add auth module * env: add gitignore * feat: application.yml and etc env * feat: auth module * feat: customer module * feat: designer module * feat: domain module * feat: persistence module * feat: local token exp update * env: temp app key * env: hide kakao client key
- Loading branch information
1 parent
2b359ae
commit e1813e5
Showing
85 changed files
with
1,866 additions
and
87 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
bootJar { | ||
enabled = false | ||
} | ||
|
||
jar { | ||
enabled = true | ||
} | ||
|
||
dependencies { | ||
implementation(project(':peauty-domain')) | ||
implementation(project(':peauty-cache')) | ||
implementation 'org.springframework.boot:spring-boot-starter-web' | ||
implementation("org.springframework.boot:spring-boot-starter-security") | ||
implementation("org.springframework.boot:spring-boot-starter-oauth2-client") | ||
implementation("com.google.api-client:google-api-client-jackson2:2.2.0") | ||
implementation("com.google.api-client:google-api-client:2.2.0") | ||
implementation 'io.jsonwebtoken:jjwt-api:0.11.5' | ||
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' | ||
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' | ||
} |
12 changes: 12 additions & 0 deletions
12
peauty-auth/src/main/java/com/peauty/auth/annotation/AccessToken.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,12 @@ | ||
package com.peauty.auth.annotation; | ||
|
||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Target(ElementType.PARAMETER) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface AccessToken { | ||
} |
11 changes: 11 additions & 0 deletions
11
peauty-auth/src/main/java/com/peauty/auth/annotation/RefreshToken.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,11 @@ | ||
package com.peauty.auth.annotation; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Target(ElementType.PARAMETER) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface RefreshToken { | ||
} |
12 changes: 12 additions & 0 deletions
12
peauty-auth/src/main/java/com/peauty/auth/annotation/SignedUser.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,12 @@ | ||
package com.peauty.auth.annotation; | ||
|
||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Target(ElementType.PARAMETER) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface SignedUser { | ||
} |
32 changes: 32 additions & 0 deletions
32
peauty-auth/src/main/java/com/peauty/auth/client/AppleAuthClient.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,32 @@ | ||
package com.peauty.auth.client; | ||
|
||
import com.peauty.domain.exception.PeautyException; | ||
import com.peauty.domain.response.PeautyResponseCode; | ||
import com.peauty.auth.properties.OAuthProperties; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.client.RestClient; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class AppleAuthClient implements ExternalAuthClient { | ||
|
||
private final RestClient restClient; | ||
private final OAuthProperties oAuthProperties; | ||
|
||
@Override | ||
public OidcPublicKeyList getPublicKeys() { | ||
OidcPublicKeyList publicKeys = restClient.get() | ||
.uri(oAuthProperties.applePublicKeyUrl()) | ||
.retrieve() | ||
.body(OidcPublicKeyList.class); | ||
|
||
if (publicKeys == null) { | ||
throw new PeautyException(PeautyResponseCode.APPLE_AUTH_CLIENT_ERROR); | ||
} | ||
|
||
return publicKeys; | ||
} | ||
|
||
|
||
} |
5 changes: 5 additions & 0 deletions
5
peauty-auth/src/main/java/com/peauty/auth/client/ExternalAuthClient.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.peauty.auth.client; | ||
|
||
public interface ExternalAuthClient { | ||
OidcPublicKeyList getPublicKeys(); | ||
} |
58 changes: 58 additions & 0 deletions
58
peauty-auth/src/main/java/com/peauty/auth/client/KakaoAuthClient.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,58 @@ | ||
package com.peauty.auth.client; | ||
|
||
|
||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.peauty.domain.exception.PeautyException; | ||
import com.peauty.domain.response.PeautyResponseCode; | ||
import com.peauty.auth.properties.OAuthProperties; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.util.LinkedMultiValueMap; | ||
import org.springframework.util.MultiValueMap; | ||
import org.springframework.web.client.RestClient; | ||
import org.springframework.web.util.UriComponentsBuilder; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class KakaoAuthClient implements ExternalAuthClient { | ||
|
||
private final RestClient restClient; | ||
private final OAuthProperties oAuthProperties; | ||
|
||
@Override | ||
public OidcPublicKeyList getPublicKeys() { | ||
OidcPublicKeyList publicKeys = restClient.get() | ||
.uri(oAuthProperties.kakaoPublicKeyInfo()) | ||
.retrieve() | ||
.body(OidcPublicKeyList.class); | ||
|
||
if (publicKeys == null) { | ||
throw new PeautyException(PeautyResponseCode.KAKAO_AUTH_CLIENT_ERROR); | ||
} | ||
|
||
return publicKeys; | ||
} | ||
|
||
public String getIdTokenFromKakao(String authCode) { | ||
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>(); | ||
formData.add("grant_type", "authorization_code"); | ||
formData.add("client_id", oAuthProperties.kakaoClientId()); | ||
formData.add("redirect_uri", oAuthProperties.kakaoRedirectUrl()); | ||
formData.add("code", authCode); | ||
String response = restClient.post() | ||
.uri("https://kauth.kakao.com/oauth/token") | ||
.header("Content-Type", "application/x-www-form-urlencoded;charset=utf-8") | ||
.body(formData) | ||
.retrieve() | ||
.body(String.class); | ||
try { | ||
JsonNode node = new ObjectMapper().readTree(response); | ||
return node.get("id_token").asText(); | ||
} catch (Exception e) { | ||
throw new PeautyException(PeautyResponseCode.INTERNAL_SERVER_ERROR); | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
peauty-auth/src/main/java/com/peauty/auth/client/OidcPublicKey.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,10 @@ | ||
package com.peauty.auth.client; | ||
|
||
public record OidcPublicKey( | ||
String kid, | ||
String kty, | ||
String alg, | ||
String use, | ||
String n, | ||
String e | ||
) {} |
24 changes: 24 additions & 0 deletions
24
peauty-auth/src/main/java/com/peauty/auth/client/OidcPublicKeyList.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.peauty.auth.client; | ||
|
||
import com.peauty.domain.exception.PeautyException; | ||
import com.peauty.domain.response.PeautyResponseCode; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
import java.util.List; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class OidcPublicKeyList { | ||
|
||
private List<OidcPublicKey> keys; | ||
|
||
public OidcPublicKey getMatchedKey(String kid, String alg) { | ||
return keys.stream() | ||
.filter(key -> key.kid().equals(kid) && key.alg().equals(alg)) | ||
.findFirst() | ||
.orElseThrow(() -> new PeautyException(PeautyResponseCode.INTERNAL_SERVER_ERROR)); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
peauty-auth/src/main/java/com/peauty/auth/config/JwtConfig.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.peauty.auth.config; | ||
|
||
import com.peauty.auth.properties.JwtProperties; | ||
import io.jsonwebtoken.io.Decoders; | ||
import io.jsonwebtoken.security.Keys; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
import java.security.Key; | ||
|
||
@Configuration | ||
@RequiredArgsConstructor | ||
@EnableConfigurationProperties(JwtProperties.class) | ||
public class JwtConfig { | ||
|
||
private final JwtProperties jwtProperties; | ||
|
||
@Bean | ||
public Key key() { | ||
return Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtProperties.secretKey())); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
peauty-auth/src/main/java/com/peauty/auth/config/OAuthConfig.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,41 @@ | ||
package com.peauty.auth.config; | ||
|
||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; | ||
import com.google.api.client.http.javanet.NetHttpTransport; | ||
import com.google.api.client.json.gson.GsonFactory; | ||
import com.peauty.auth.properties.JwtProperties; | ||
import com.peauty.auth.properties.OAuthProperties; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
import org.springframework.boot.web.client.RestTemplateBuilder; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.client.RestClient; | ||
|
||
import java.time.Duration; | ||
import java.util.Collections; | ||
|
||
@Configuration | ||
@RequiredArgsConstructor | ||
@EnableConfigurationProperties(OAuthProperties.class) | ||
public class OAuthConfig { | ||
|
||
private final OAuthProperties oAuthProperties; | ||
|
||
@Bean | ||
public GoogleIdTokenVerifier googleIdTokenVerifier() { | ||
return new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), GsonFactory.getDefaultInstance()) | ||
.setAudience(Collections.singletonList(oAuthProperties.googleClientId())) | ||
.build(); | ||
} | ||
|
||
// For AuthClient | ||
@Bean | ||
public RestClient restClient() { | ||
var restTemplate = new RestTemplateBuilder() | ||
.setConnectTimeout(Duration.ofSeconds(10)) | ||
.setReadTimeout(Duration.ofSeconds(5)) | ||
.build(); | ||
return RestClient.create(restTemplate); | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
peauty-auth/src/main/java/com/peauty/auth/config/SecurityConfig.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,73 @@ | ||
package com.peauty.auth.config; | ||
|
||
import com.peauty.auth.filter.JwtAuthenticationFilter; | ||
import com.peauty.auth.filter.JwtExceptionFilter; | ||
import com.peauty.auth.properties.JwtProperties; | ||
import com.peauty.auth.properties.OAuthProperties; | ||
import com.peauty.auth.resolver.AccessTokenResolver; | ||
import com.peauty.auth.resolver.RefreshTokenResolver; | ||
import com.peauty.auth.resolver.SignedUserResolver; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.boot.context.properties.ConfigurationPropertiesScan; | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.context.annotation.PropertySource; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | ||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; | ||
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; | ||
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; | ||
import org.springframework.security.config.annotation.web.configurers.SessionManagementConfigurer; | ||
import org.springframework.security.config.http.SessionCreationPolicy; | ||
import org.springframework.security.web.SecurityFilterChain; | ||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
|
||
import java.util.List; | ||
|
||
// TODO 의존하는 모듈에서의 자체 확장 가능하게 ConditionalMissingBean? | ||
@Configuration | ||
@EnableWebSecurity | ||
@RequiredArgsConstructor | ||
public class SecurityConfig implements WebMvcConfigurer { | ||
|
||
private final JwtAuthenticationFilter jwtAuthenticationFilter; | ||
private final JwtExceptionFilter jwtExceptionFilter; | ||
|
||
@Bean | ||
public SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception { | ||
return http | ||
.httpBasic(AbstractHttpConfigurer::disable) | ||
.csrf(AbstractHttpConfigurer::disable) | ||
.formLogin(AbstractHttpConfigurer::disable) | ||
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) | ||
.sessionManagement(this::setSessionManagement) | ||
.authorizeHttpRequests(this::setAuthorizePath) | ||
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) | ||
.addFilterBefore(jwtExceptionFilter, JwtAuthenticationFilter.class) | ||
.build(); | ||
} | ||
|
||
private void setSessionManagement(SessionManagementConfigurer<HttpSecurity> sessionManagement) { | ||
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS); | ||
} | ||
|
||
private void setAuthorizePath(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry authorize) { | ||
authorize.requestMatchers( | ||
"/sign-out" | ||
).hasAnyRole("CUSTOMER", "DESIGNER", "ADMIN") | ||
.requestMatchers( | ||
"/**" | ||
).permitAll() | ||
.anyRequest().authenticated(); | ||
} | ||
|
||
@Override | ||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { | ||
resolvers.add(new SignedUserResolver()); | ||
resolvers.add(new AccessTokenResolver()); | ||
resolvers.add(new RefreshTokenResolver()); | ||
} | ||
} |
Oops, something went wrong.