JWT 발행을 위한 인증 서버 수정
This commit is contained in:
@@ -48,14 +48,20 @@
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-security</artifactId>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-oauth2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-jwt</artifactId>
|
||||
<version>1.1.1.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.assu.cloud.authservice.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Configuration
|
||||
public class CustomConfig {
|
||||
|
||||
@Value("${signing.key}")
|
||||
private String jwtSigningKey = "";
|
||||
|
||||
public String getJwtSigningKey() {
|
||||
return jwtSigningKey;
|
||||
}
|
||||
}
|
||||
@@ -8,25 +8,60 @@ import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
|
||||
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* JWTTokenStoreConfig 에서 서명하고 생성한 JWT 토큰을 OAuth2 인증 서버로 연결
|
||||
*
|
||||
* OAuth2 인증 서버에 등록될 애플리케이션 정의
|
||||
* AuthorizationServerConfigurerAdapter: 스프링 시큐리티 핵심부, 핵심 인증 및 인가 기능 수행하는 기본 메커니즘 제공
|
||||
*/
|
||||
@Configuration
|
||||
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
|
||||
public class JWTOAuth2Config extends AuthorizationServerConfigurerAdapter {
|
||||
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final UserDetailsService userDetailsService;
|
||||
private final TokenStore tokenStore;
|
||||
private final DefaultTokenServices defaultTokenServices;
|
||||
private final JwtAccessTokenConverter jwtAccessTokenConverter;
|
||||
private final JWTTokenEnhancer jwtTokenEnhancer;
|
||||
|
||||
public OAuth2Config(AuthenticationManager authenticationManager, @Qualifier("userDetailsServiceBean") UserDetailsService userDetailsService) {
|
||||
|
||||
public JWTOAuth2Config(AuthenticationManager authenticationManager, @Qualifier("userDetailsServiceBean") UserDetailsService userDetailsService,
|
||||
TokenStore tokenStore, DefaultTokenServices defaultTokenServices,
|
||||
JwtAccessTokenConverter jwtAccessTokenConverter, JWTTokenEnhancer jwtTokenEnhancer) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
this.userDetailsService = userDetailsService;
|
||||
this.tokenStore = tokenStore;
|
||||
this.defaultTokenServices = defaultTokenServices;
|
||||
this.jwtAccessTokenConverter = jwtAccessTokenConverter;
|
||||
this.jwtTokenEnhancer = jwtTokenEnhancer;
|
||||
}
|
||||
|
||||
/**
|
||||
* AuthorizationServerConfigurerAdapter 안에서 사용될 여러 컴포넌트 정의
|
||||
* 여기선 스프링에 토큰 스토어, 액세스 토큰 컨버터, 토큰 엔헨서, 기본 인증 관리자와 사용자 상세 서비스를 이용한다고 선언
|
||||
*/
|
||||
@Override
|
||||
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
|
||||
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
|
||||
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(jwtTokenEnhancer, jwtAccessTokenConverter));
|
||||
|
||||
endpoints.tokenStore(tokenStore) // JWT, JWTTokenStoreConfig 에서 정의한 토큰 저장소
|
||||
.accessTokenConverter(jwtAccessTokenConverter) // JWT, 스프링 시큐리티 OAuth2 가 JWT 사용하도록 연결
|
||||
.tokenEnhancer(tokenEnhancerChain) // JWT
|
||||
.authenticationManager(authenticationManager)
|
||||
.userDetailsService(userDetailsService);
|
||||
}
|
||||
|
||||
/**
|
||||
* 인증 서버에 등록될 클라이언트 정의
|
||||
* 즉, OAuth2 서비스로 보호되는 서비스에 접근할 수 있는 클라이언트 애플리케이션 등록
|
||||
* 즉, OAuth2 서비스로 보호되는서비스에 접근할 수 있는 클라이언트 애플리케이션 등록
|
||||
*/
|
||||
@Override
|
||||
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
|
||||
@@ -36,14 +71,4 @@ public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
|
||||
.authorizedGrantTypes("refresh_token", "password", "client_credentials") // OAuth2 에서 지원하는 인가 그랜트 타입, 여기선 패스워드/클라이언트 자격증명 그랜트타입
|
||||
.scopes("webclient", "mobileclient"); // 토큰 요청 시 애플리케이션의 수행 경계 정의
|
||||
}
|
||||
|
||||
/**
|
||||
* AuthorizationServerConfigurerAdapter 안에서 사용될 여러 컴포넌트 정의
|
||||
* 여기선 스프링에 기본 인증 관리자와 사용자 상세 서비스를 이용한다고 선언
|
||||
*/
|
||||
@Override
|
||||
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
|
||||
endpoints.authenticationManager(authenticationManager)
|
||||
.userDetailsService(userDetailsService);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.assu.cloud.authservice.security;
|
||||
|
||||
import com.assu.cloud.authservice.config.CustomConfig;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 액세스 토큰에 추가 정보 삽입
|
||||
*/
|
||||
@Configuration
|
||||
public class JWTTokenEnhancer implements TokenEnhancer {
|
||||
|
||||
private String getUserId(String userName){
|
||||
// DB 로 유저 아이디 조회
|
||||
return "12345";
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
|
||||
Map<String, Object> additionalInfo = new HashMap<>();
|
||||
String userId = getUserId(authentication.getName());
|
||||
|
||||
additionalInfo.put("userId", userId);
|
||||
|
||||
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
|
||||
return accessToken;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.assu.cloud.authservice.security;
|
||||
|
||||
import com.assu.cloud.authservice.config.CustomConfig;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
|
||||
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
|
||||
|
||||
/**
|
||||
* 인증 서버가 JWT 토큰을 생성, 서명, 해석하는 방법 지정
|
||||
*/
|
||||
@Configuration
|
||||
public class JWTTokenStoreConfig {
|
||||
|
||||
private final CustomConfig customConfig;
|
||||
|
||||
public JWTTokenStoreConfig(CustomConfig customConfig) {
|
||||
this.customConfig = customConfig;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TokenStore tokenStore() {
|
||||
return new JwtTokenStore(jwtAccessTokenConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* 서비스에 전달된 토큰에서 데이터를 읽는데 사용
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
@Primary // 특정 타입의 빈이 둘 이상인 경우 (여기선 DefaultTokenServices) @Primary 로 지정된 타입을 자동 주입
|
||||
public DefaultTokenServices tokenServices() {
|
||||
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
|
||||
defaultTokenServices.setTokenStore(tokenStore());
|
||||
defaultTokenServices.setSupportRefreshToken(true);
|
||||
return defaultTokenServices;
|
||||
}
|
||||
|
||||
/**
|
||||
* JWT 와 OAuth2 인증 서버 사이의 변환기
|
||||
* 토큰 서명에 사용되는 서명키 사용 (여기선 대칭 키)
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public JwtAccessTokenConverter jwtAccessTokenConverter() {
|
||||
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
|
||||
converter.setSigningKey(customConfig.getJwtSigningKey()); // 토큰 서명에 사용되는 서명키 정의
|
||||
return converter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TokenEnhancer jwtTokenEnhancer() {
|
||||
return new JWTTokenEnhancer();
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ spring:
|
||||
uri: https://github.com/assu10/config-repo.git
|
||||
username: assu10
|
||||
password: '{cipher}f38ff3546220bbac52d81c132916b1b1fd7c3cfdcfdf408760d1c4bf0b4ee97c'
|
||||
search-paths: member-service, event-service, eurekaserver, zuulserver # 구성 파일을 찾을 폴더 경로
|
||||
search-paths: member-service, event-service, eurekaserver, zuulserver, auth-service # 구성 파일을 찾을 폴더 경로
|
||||
encrypt:
|
||||
enabled: false
|
||||
|
||||
|
||||
Reference in New Issue
Block a user