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

如何向Azure AD Java SDK的UsernamePasswordCredentialBuilder传入客户端密钥

解决方案:机密客户端ROPC流的实现

首先明确:UsernamePasswordCredentialBuilder是Azure Identity SDK为公共客户端应用设计的ROPC(资源所有者密码凭证)认证方式,因此不支持传入客户端密钥(client secret)。而你在Postman中使用的是机密客户端的ROPC流——该流需要同时验证客户端身份(通过client secret)和用户身份,Azure Identity SDK中没有直接对应的Credential类,可通过以下两种方式实现:

方式一:使用MSAL4J实现机密客户端ROPC流

MSAL4J(Microsoft Authentication Library for Java)支持机密客户端的ROPC认证,步骤如下:

  1. 添加MSAL4J依赖到pom.xml:
<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>msal4j</artifactId>
    <version>1.14.0</version>
</dependency>
  1. 编写认证及Graph API调用代码:
import com.microsoft.graph.authentication.TokenCredentialAuthProvider;
import com.microsoft.graph.models.extensions.User;
import com.microsoft.graph.requests.extensions.GraphServiceClient;
import com.microsoft.aad.msal4j.*;

import java.util.Collections;
import java.util.concurrent.CompletableFuture;

public class RopcConfidentialClientExample {
    public static void main(String[] args) throws Exception {
        String clientId = "YOUR_CLIENT_ID";
        String clientSecret = "YOUR_CLIENT_SECRET";
        String tenantId = "YOUR_TENANT_ID";
        String username = "USER_USERNAME";
        String password = "USER_PASSWORD";
        String scope = "https://graph.microsoft.com/.default";

        // 初始化机密客户端
        ConfidentialClientApplication client = ConfidentialClientApplication.builder(
                clientId,
                ClientCredentialFactory.createFromSecret(clientSecret))
                .authority("https://login.microsoftonline.com/" + tenantId)
                .build();

        // 构造ROPC请求参数
        UserNamePasswordParameters parameters = UserNamePasswordParameters.builder(
                Collections.singleton(scope),
                username,
                password.toCharArray())
                .build();

        // 获取访问令牌
        CompletableFuture<IAuthenticationResult> future = client.acquireToken(parameters);
        IAuthenticationResult result = future.get();
        String accessToken = result.accessToken();

        // 使用令牌初始化GraphServiceClient
        TokenCredentialAuthProvider authProvider = new TokenCredentialAuthProvider(Collections.singleton(scope),
                requestContext -> CompletableFuture.completedFuture(accessToken));
        GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();

        // 调用Graph API示例
        User me = graphClient.me().buildRequest().get();
        System.out.println(me.displayName);
    }
}

方式二:手动构造HTTP请求获取令牌

如果不想引入MSAL4J依赖,可以直接向Azure AD令牌端点发送POST请求获取令牌,再传入GraphServiceClient:

import com.microsoft.graph.authentication.TokenCredentialAuthProvider;
import com.microsoft.graph.models.extensions.User;
import com.microsoft.graph.requests.extensions.GraphServiceClient;
import okhttp3.*;

import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.CompletableFuture;

public class RopcHttpExample {
    public static void main(String[] args) throws IOException {
        String clientId = "YOUR_CLIENT_ID";
        String clientSecret = "YOUR_CLIENT_SECRET";
        String tenantId = "YOUR_TENANT_ID";
        String username = "USER_USERNAME";
        String password = "USER_PASSWORD";
        String scope = "https://graph.microsoft.com/.default";

        // 构造令牌请求
        OkHttpClient client = new OkHttpClient();
        RequestBody formBody = new FormBody.Builder()
                .add("client_id", clientId)
                .add("client_secret", clientSecret)
                .add("grant_type", "password")
                .add("username", username)
                .add("password", password)
                .add("scope", scope)
                .build();

        Request request = new Request.Builder()
                .url("https://login.microsoftonline.com/" + tenantId + "/oauth2/v2.0/token")
                .post(formBody)
                .build();

        Response response = client.newCall(request).execute();
        String responseBody = response.body().string();
        // 解析JSON获取access_token(生产环境建议用Jackson等JSON库解析)
        String accessToken = responseBody.split("\"access_token\":\"")[1].split("\"")[0];

        // 初始化GraphServiceClient
        TokenCredentialAuthProvider authProvider = new TokenCredentialAuthProvider(Collections.singleton(scope),
                requestContext -> CompletableFuture.completedFuture(accessToken));
        GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();

        // 调用Graph API示例
        User me = graphClient.me().buildRequest().get();
        System.out.println(me.displayName);
    }
}

注意事项

  • ROPC流不推荐用于生产环境,因为需要存储用户密码,存在安全风险,建议优先使用授权码流等更安全的认证方式。
  • 确保你的Azure AD应用已配置为机密客户端(无需开启"Allow public client flows"),并已授予所需的委托权限(需管理员或用户同意,取决于权限类型)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 15:23:15