我在 Net Framework 4.8 应用程序中使用 Npgsql 和 EF Core (3.1)。由于公司基础设施/政策的原因,我无法升级到更高版本。我正在使用 Azure 托管身份 连接到数据库。我正在使用 Unity 进行依赖注入。
所有这些都工作得很好,只是一小时后我的托管身份访问令牌(用作数据库连接的密码)过期了。然后显然连接也不再有效。有没有优雅的方法来解决这个问题?
在启动过程中,我为我的托管身份生成 AccessToken:
HttpClient httpClient = new HttpClient();
FormUrlEncodedContent content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "client_credentials"),
new KeyValuePair<string, string>("client_id", ClientId),
new KeyValuePair<string, string>("client_secret", Secret),
new KeyValuePair<string, string>("scope", "https://management.azure.com/.default"),
});
var tokenUrl = $"https://login.microsoftonline.com/{TenantId}/oauth2/token";
var response = await httpClient.PostAsync(tokenUrl, content);
var result = await response.Content.ReadAsStringAsync();
AccessTokenResponse accessTokenResponse = JsonSerializer.Deserialize<AccessTokenResponse>(result);
return accessTokenResponse.AccessToken;
然后我使用在代码中创建连接字符串
// params provided to method
return String.Format("Server={0};Database={1};Port={2};User Id={3};Password={4};SSLMode=Prefer",
databaseHost,
databaseName,
5432,
databaseUser,
accessToken);
最后我使用 Unity 添加 Npgsql DbContext:
var optionsBuilder = new DbContextOptionsBuilder<DbContext>();
optionsBuilder.UseNpgsql(connectionString: databaseConnectionString,
npgsqlOptionsAction: o =>
{
o.UseNetTopologySuite();
o.CommandTimeout(3600);
})
// IUnityContainer
container.RegisterInstance(optionsBuilder.Options);
较新版本的 Npgsql 具有访问令牌轮换的特定功能(docs);但这样的旧版本则不支持(请注意,此时 3.1 已不再支持)。当身份验证令牌更改时,您可能必须手动重建连接字符串,并确保在任何地方都使用它。