기존 InMemory 방식에서 JdbcTokenStore방식으로 변경이다.
CREATE TABLE oauth_client_details (
client_id VARCHAR(256) PRIMARY KEY,
resource_ids VARCHAR(256),
client_secret VARCHAR(256),
scope VARCHAR(256),
authorized_grant_types VARCHAR(256),
web_server_redirect_uri VARCHAR(256),
authorities VARCHAR(256),
access_token_validity INT,
refresh_token_validity INT,
additional_information VARCHAR(4096),
autoapprove VARCHAR(256)
);
CREATE TABLE oauth_client_token (
token_id VARCHAR(256),
token MEDIUMBLOB,
authentication_id VARCHAR(256) PRIMARY KEY,
user_name VARCHAR(256),
client_id VARCHAR(256)
);
CREATE TABLE oauth_access_token (
token_id VARCHAR(256),
token MEDIUMBLOB,
authentication_id VARCHAR(256) PRIMARY KEY,
user_name VARCHAR(256),
client_id VARCHAR(256),
authentication MEDIUMBLOB,
refresh_token VARCHAR(256)
);
CREATE TABLE oauth_refresh_token (
token_id VARCHAR(256),
token MEDIUMBLOB,
authentication MEDIUMBLOB
);
CREATE TABLE oauth_code (
code VARCHAR(256),
authentication MEDIUMBLOB
);
CREATE TABLE oauth_approvals (
userId VARCHAR(256),
clientId VARCHAR(256),
scope VARCHAR(256),
status VARCHAR(10),
expiresAt DATETIME,
lastModifiedAt DATETIME
);
CREATE TABLE ClientDetails (
appId VARCHAR(256) PRIMARY KEY,
resourceIds VARCHAR(256),
appSecret VARCHAR(256),
scope VARCHAR(256),
grantTypes VARCHAR(256),
redirectUrl VARCHAR(256),
authorities VARCHAR(256),
access_token_validity INT,
refresh_token_validity INT,
additionalInformation VARCHAR(4096),
autoApproveScopes VARCHAR(256)
);
INSERT INTO testmysql.oauth_client_details (client_id, resource_ids, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove)
VALUES ('clientId', null, '{noop}secretKey', 'read,write', 'authorization_code,password,refresh_token,client_credentials', 'http://localhost:7070/callback', 'GENERAL', 60, 3600, null, 'true');
먼저 데이터베이스에 해당 스키마들을 저장한다.
스프링에서 제공되는 Default Schema는 이 곳에서 찾을 수 있다.
@RequiredArgsConstructor
@EnableAuthorizationServer
@Configuration
public class Oauth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
private final UserDetailService userDetailService;
private final AuthenticationManager authenticationManager;
private final DataSource dataSource;
@Bean
public TokenStore tokenStore() { return new JdbcTokenStore(dataSource); }
@Bean
public ApprovalStore approvalStore() { return new JdbcApprovalStore(dataSource); }
@Bean
public JdbcAuthorizationCodeServices jdbcAuthorizationCodeServices() { return new JdbcAuthorizationCodeServices(dataSource); }
@Bean
public TokenEnhancer tokenEnhancer() { return new CustomTokenEnhancer(); }
// @Bean // 커스텀해서 사용할듯함 / endpoints에 추가못함
// public JdbcClientDetailsService jdbcClientDetailsService() { return new JdbcClientDetailsService(dataSource); }
@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security.checkTokenAccess("permitAll()"); // 토큰유효성(/token/check_token) 접근을 위해 설정
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.authenticationManager(authenticationManager) // grant_type password 를 사용하기 위함 (manager 지정 안할시 password type 으로 토큰 발행시 Unsupported grant type: password 오류 발생)
.userDetailsService(userDetailService) // refresh token 발행시 유저 정보 검사 하는데 사용하는 서비스 설정
.tokenStore(tokenStore()) // oauth_access_token 에 저장
.approvalStore(approvalStore()) // oauth_approvals 에 저장
.authorizationCodeServices(jdbcAuthorizationCodeServices())
.tokenEnhancer(tokenEnhancer()) // 토큰 발급시 추가정보 입력
;
}
}
InMemory방식과 비교했을 때clients.jdbc(dataSource);
으로 설정으로 한방에 해결이 되고 데이터베이스에 저장되어 관리가 되어 데이터들을 시각적으로 바로 확인가능해진다.