You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

容器应用通过用户分配托管身份连接SQL数据库时MSI令牌获取失败

用户分配托管身份连接Azure SQL数据库失败:MSI Token获取失败

报错信息

ERROR 1 --- [main] com.zaxxer.hikari.pool.HikariPool: HikariPool-1 - Exception during pool initialization.
com.microsoft.sqlserver.jdbc.SQLServerException: MSI Token failure: Failed to acquire token from MSI Endpoint
at com.microsoft.sqlserver.jdbc.SQLServerSecurityUtility.getMSIAuthToken(SQLServerSecurityUtility.java:499) ~[mssql-jdbc-11.2.3.jre17.jar:na]
...

应用配置

pom.xml

...
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.1</version>
        <relativePath />
    </parent>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-identity</artifactId>
            <version>1.5.4</version>
        </dependency>
    </dependencies>
...

application.properties

spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
spring.datasource.url=jdbc:sqlserver://danieltestsqlserver1101.database.windows.net:1433;databaseName=testdatabase01;msiClientId=<managed-identity-client-id>;authentication=ActiveDirectoryMSI;

Azure配置步骤

  • 创建用户分配托管身份“mi-test-app”
  • 创建AD组“DB admin”,将“mi-test-app”和主用户添加为成员与所有者
  • 创建SQL Server,将“DB admin”组设置为服务器管理员
  • 为SQL Server创建专用终结点并禁用公网访问
  • 创建专用DNS区域并配置虚拟网络链接
  • 在SQL数据库中执行以下脚本:
    CREATE USER [mi-test-app] FROM EXTERNAL PROVIDER;
    ALTER ROLE db_datareader ADD MEMBER [mi-test-app];
    ALTER ROLE db_datawriter ADD MEMBER [mi-test-app];
    ALTER ROLE db_ddladmin ADD MEMBER [mi-test-app];
    GO
    
  • 创建带独立环境的容器应用,添加“mi-test-app”到身份列表并重启修订版本

排查与解决步骤

1. 验证容器应用的托管身份关联

  • 确认容器应用的身份配置中,用户分配托管身份“mi-test-app”已被正确添加,且状态为“已启用”
  • 检查容器应用的环境变量是否设置了AZURE_CLIENT_ID,值为托管身份的Client ID(azure-identity库需要此变量明确指定用户分配身份)

2. 修正JDBC认证配置与依赖版本

  • Spring Boot 3.x搭配mssql-jdbc 11.x时,推荐使用ActiveDirectoryDefault认证模式替代ActiveDirectoryMSI,该模式会自动通过azure-identity库获取令牌
  • 更新azure-identity到最新稳定版本(如1.12.0),旧版本在容器环境中可能存在令牌获取兼容性问题
  • 修改JDBC URL为:
    spring.datasource.url=jdbc:sqlserver://danieltestsqlserver1101.database.windows.net:1433;databaseName=testdatabase01;authentication=ActiveDirectoryDefault;
    
  • 确保容器应用环境变量中添加AZURE_CLIENT_ID=<managed-identity-client-id>

3. 确认SQL Server与托管身份的权限同步

  • 登录SQL Server,执行SELECT name, type_desc FROM sys.server_principals WHERE name = 'mi-test-app',确认托管身份已存在于服务器主体中
  • 若未找到,需重新同步AD组权限:可先移除“DB admin”组的服务器管理员权限,等待5分钟后重新添加,再验证服务器主体是否出现

4. 排查网络连通性

  • 确认容器应用所在虚拟网络与SQL Server专用终结点所在虚拟网络已连通(对等连接或同一VNet)
  • 检查专用DNS区域的A记录是否正确指向SQL Server专用终结点的IP,且容器应用能解析该域名
  • 验证容器应用能否访问Azure实例元数据服务(IMDS):在容器内执行curl http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://database.windows.net/,若无法访问则需检查容器环境的网络策略

5. 启用调试日志定位问题

  • 在application.properties中添加日志配置:
    logging.level.com.azure.identity=DEBUG
    logging.level.com.microsoft.sqlserver.jdbc=DEBUG
    
  • 查看容器应用的详细日志,获取令牌请求的具体错误原因(如权限不足、身份未找到、网络超时等)

内容的提问来源于stack exchange,提问作者dgolive

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 22:00:58