OAuth2.0 Authorization Server JDBC 전환(작성중)

아이스__아메리·2024년 4월 1일
0

도입기&적용기

목록 보기
7/7
post-custom-banner

기존 InMemory 방식에서 JdbcTokenStore방식으로 변경이다.

oauth2.0 스키마

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);으로 설정으로 한방에 해결이 되고 데이터베이스에 저장되어 관리가 되어 데이터들을 시각적으로 바로 확인가능해진다.

profile
츠케멘 좋아
post-custom-banner

0개의 댓글