Kotlin Spring Boot中实现Azure Graph API OAuth2令牌自动刷新与持久化
解决方案:持久化OAuth2令牌实现自动刷新(Kotlin Spring Boot)
核心思路
借助Microsoft Graph SDK的令牌缓存扩展能力,将访问令牌、刷新令牌等缓存数据持久化到数据库,重启应用时自动读取缓存完成令牌刷新,无需重复手动认证。
最小改动步骤
1. 定义令牌存储实体(JPA示例)
创建数据库实体类,用于存储令牌缓存的完整数据:
import jakarta.persistence.* @Entity @Table(name = "oauth2_token_cache") class OAuth2TokenCache( @Id @Column(unique = true) val userId: String, // 固定为目标邮箱support@ourcompany.com.au @Column(length = 2000) val cacheContent: String, // SDK生成的完整令牌缓存JSON val lastUpdated: Long = System.currentTimeMillis() )
2. 实现自定义令牌缓存序列化器
对接数据库操作,实现SDK要求的ITokenCacheSerializer接口:
import com.microsoft.graph.authentication.ITokenCacheSerializer import org.springframework.stereotype.Component import javax.persistence.EntityManager @Component class DatabaseTokenCache( private val entityManager: EntityManager, private val targetUserId: String = "support@ourcompany.com.au" ) : ITokenCacheSerializer { override fun serialize(tokenCache: String) { val existingCache = entityManager.find(OAuth2TokenCache::class.java, targetUserId) ?: OAuth2TokenCache(userId = targetUserId, cacheContent = tokenCache) existingCache.cacheContent = tokenCache existingCache.lastUpdated = System.currentTimeMillis() entityManager.merge(existingCache) } override fun deserialize(): String? { return entityManager.find(OAuth2TokenCache::class.java, targetUserId)?.cacheContent } }
3. 修改原有认证代码,注入自定义缓存
在设备码流认证逻辑中,配置使用数据库缓存替换默认文件缓存:
import com.microsoft.graph.authentication.DeviceCodeCredentialBuilder import com.microsoft.graph.authentication.TokenCachePersistenceOptions import com.microsoft.graph.requests.GraphServiceClient import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @Service class GraphAuthService( @Autowired private val dbTokenCache: DatabaseTokenCache ) { fun getAuthenticatedClient(): GraphServiceClient<*> { val cacheOptions = TokenCachePersistenceOptions().apply { isEnablePersistence = true serializer = dbTokenCache } val credential = DeviceCodeCredentialBuilder() .clientId("your-client-id") // 替换为你的Azure AD客户端ID .tenantId("your-tenant-id") // 替换为你的租户ID .deviceCodeCallback { codeInfo -> // 仅首次认证时触发,后续自动刷新不会执行此逻辑 println("请访问 ${codeInfo.verificationUri} 输入代码: ${codeInfo.userCode}") } .tokenCachePersistenceOptions(cacheOptions) .build() return GraphServiceClient.builder() .authenticationProvider(credential) .buildClient() } }
4. 验证自动刷新逻辑
- 首次启动:控制台会输出设备码提示,手动完成认证后,令牌缓存会自动写入数据库
- 后续重启:SDK会自动读取数据库中的缓存,若令牌未过期直接使用;若已过期则自动调用刷新令牌获取新凭证,全程无需人工干预
关键注意事项
- 开启Spring JPA自动建表(
spring.jpa.hibernate.ddl-auto=update),确保oauth2_token_cache表自动生成 - 确保Azure AD应用已配置
Mail.Read等必要权限,且已完成管理员同意 - 令牌缓存的JSON结构由SDK维护,直接存储完整字符串可避免解析错误
内容的提问来源于stack exchange,提问作者Michael NGV
相关产品推荐
相关产品推荐

