我们有一个PostgreSQL单一服务实例在Azure中运行,它是Azure AD集成的。因此,要通过psql
连接,我遵循以下步骤:
- 通过
az login
登录 - 检索访问令牌
$env:PGPASSWORD=$(az account get-access-token --resource-type oss-rdbms --query accessToken --output tsv)
- 登录
psql "host=single-server-instance.postgres.database.azure.com user=aad_group@single-server-instance dbname=demodb"
到目前为止还不错。但是我该如何使用Spring Data JPA来实现这一点呢?
这就是我当前的application.properties
文件的样子。当然,我不想一次又一次地插入访问令牌。
logging.level.org.hibernate.SQL=DEBUG
spring.datasource.url=jdbc:postgresql://single-server-instance.postgres.database.azure.com:5432/demodb
spring.datasource.username=aad_group@single-server-instance
spring.datasource.password=eyJ...there goes the access token
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
这是我在build.gradle
中的依赖项。
// ...
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
// ...
问题:
- 我应该将
spring.datasource
和spring.jpa
配置部分移动到我的代码中,并从那里向spring.datasource.password
提供访问令牌吗?如果是,我该怎么做?它应该去哪里 - 如何检索访问令牌并将其传递给Spring Data
- 我应该如何处理访问令牌的缓存?我必须处理刷新令牌和访问令牌到期问题吗
我们扩展了HikairDataSource并重写了其getPassword((方法,该方法在创建新连接之前调用。
import com.azure.core.credential.AccessToken;
import com.azure.core.credential.SimpleTokenCache;
import com.azure.core.credential.TokenCredential;
import com.azure.core.credential.TokenRequestContext;
import com.zaxxer.hikari.HikariDataSource;
@Component
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public class AzureAdDataSource extends HikariDataSource {
private final SimpleTokenCache cache;
public AzureAdDataSource(TokenCredential aadTokenCredential) {
this.cache = new SimpleTokenCache(() -> aadTokenCredential.getToken(createRequestContext()));
}
@Override
public String getPassword() {
final AccessToken accessToken = cache.getToken()
.retry(1L)
.blockOptional()
.orElseThrow(() -> new RuntimeException("Attempt to retrieve AAD token failed"));
return accessToken.getToken();
}
private static TokenRequestContext createRequestContext() {
return new TokenRequestContext().addScopes("https://ossrdbms-aad.database.windows.net/.default");
}
}
使用过的库:'com.azure:azure-identity:1.3.3', 'com.zaxxer:HikariCP:4.0.3'
调整属性,或在配置文件中创建AzureAdDataSource实例,而不是将其注释为Component:
spring.datasource.hikari.jdbc-url=jdbc:postgresql://single-server-instance.postgres.database.azure.com:5432/demodb
spring.datasource.hikari.username=aad_group@single-server-instance
现在Azure提供了Spring入门库,PostgreSQL就是其中之一https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/postgresql-support#connect-到azure postgresql本地,无需密码