---
# System prepended metadata

title: Utilizing `JdbcOAuth2AuthorizedClientService` to Persist Refresh Token in RDBMS
tags: [oauth, spring, refresh token]

---

# Utilizing `JdbcOAuth2AuthorizedClientService` to Persist Refresh Token in RDBMS

[TOC]

###### tags: `spring` `oauth` `refresh token`

---

## 給耐不住性子的

- 在繼承 [`WebSecurityConfigurerAdapter`](https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html) 的類中宣告一個 [`OAuth2AuthorizedClientService`](https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/oauth2/client/OAuth2AuthorizedClientService.html) 的 bean。

```java
@Configuration
public class WebSecurityConfigurerAdapterImpl extends WebSecurityConfigurerAdapter {

	/*
	 * other codes omitted for brevity
	 */

	@Bean
	public OAuth2AuthorizedClientService oAuth2AuthorizedClientService(
		JdbcOperations jdbcOperations,
		ClientRegistrationRepository clientRegistrationRepository
	) {
		return new JdbcOAuth2AuthorizedClientService(
			jdbcOperations,
			clientRegistrationRepository
		);
	}
}
```

- 建立資料表。

PostgreSQL 用的 DDL:
```sql
CREATE TABLE oauth2_authorized_client (
	client_registration_id varchar(100) NOT NULL,
	principal_name varchar(200) NOT NULL,
	access_token_type varchar(100) NOT NULL,
	access_token_value bytea NOT NULL,
	access_token_issued_at timestamp NOT NULL,
	access_token_expires_at timestamp NOT NULL,
	access_token_scopes varchar(1000) DEFAULT NULL,
	refresh_token_value bytea DEFAULT NULL,
	refresh_token_issued_at timestamp DEFAULT NULL,
	created_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
	PRIMARY KEY (client_registration_id, principal_name)
);
```

MySQL/MarisDB 用的 DDL:
```sql
CREATE TABLE oauth2_authorized_client (
	client_registration_id varchar(100) NOT NULL,
	principal_name varchar(200) NOT NULL,
	access_token_type varchar(100) NOT NULL,
	access_token_value blob NOT NULL,
	access_token_issued_at timestamp NOT NULL,
	access_token_expires_at timestamp NOT NULL,
	access_token_scopes varchar(1000) DEFAULT NULL,
	refresh_token_value blob DEFAULT NULL,
	refresh_token_issued_at timestamp DEFAULT NULL,
	created_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
	PRIMARY KEY (client_registration_id, principal_name)
);
```

其它 RDBMS 的 DDL 可透過