向 Azure Graph API 发送 POST 请求时收到 400 错误请求

Getting 400 Bad request when sending POST request to Azure Graph API

我正在尝试向 Microsoft Azure Graph API 发送 POST 请求以创建用户。 我已经参考了他们的示例 example 并且能够成功执行 GET 请求但没有 POST.

我的代码如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.naming.ServiceUnavailableException;

import org.json.JSONException;
import org.json.JSONObject;

import com.microsoft.aad.adal4j.AuthenticationContext;
import com.microsoft.aad.adal4j.AuthenticationResult;

public class CreateUser {

    private final static String AUTHORITY = "https://login.microsoftonline.com/common/";
    private final static String CLIENT_ID = "<Client_id>";

    public static void main(String args[]) throws Exception {

        try (BufferedReader br = new BufferedReader(new InputStreamReader(
                System.in))) {
            System.out.print("Enter username: ");
            String username = br.readLine();
            System.out.print("Enter password: ");
            String password = br.readLine();

            // Request access token from AAD
            AuthenticationResult result = getAccessTokenFromUserCredentials(
                    username, password);
            // Get user info from Microsoft Graph
            String userInfo = createUserInGraph(result.getAccessToken());
            System.out.print(userInfo);
        }
   }

    private static AuthenticationResult getAccessTokenFromUserCredentials(
            String username, String password) throws Exception {
        AuthenticationContext context;
        AuthenticationResult result;
        ExecutorService service = null;
        try {
            service = Executors.newFixedThreadPool(1);
            context = new AuthenticationContext(AUTHORITY, false, service);
            Future<AuthenticationResult> future = context.acquireToken(
                    "https://graph.microsoft.com", CLIENT_ID, username, password,
                    null);
            result = future.get();
        } finally {
            service.shutdown();
        }

        if (result == null) {
            throw new ServiceUnavailableException(
                    "authentication result was null");
        }
        return result;
    }

    private static String createUserInGraph(String accessToken) throws IOException {

        String jsonInputData = "{  \"accountEnabled\": true," + 
                "  \"city\": \"Delhi\"," + 
                "  \"country\": \"India\"," + 
                "  \"department\": \"Human Resources\"," + 
                "  \"displayName\": \"Adam G\"," + 
                "  \"givenName\": \"Adam\"," + 
                "  \"jobTitle\": \"Senior Human Resource Manager\"," + 
                "  \"mailNickname\": \"adamg\"," + 
                "  \"passwordPolicies\": \"DisablePasswordExpiration\"," + 
                "  \"passwordProfile\": {" + 
                "    \"password\": \"Test1234\"," + 
                "    \"forceChangePasswordNextSignIn\": false" + 
                "  }," + 
                "  \"officeLocation\": \"131/1105\"," + 
                "  \"postalCode\": \"98052\"," + 
                "  \"preferredLanguage\": \"en-US\"," + 
                "  \"state\": \"MH\"," + 
                "  \"streetAddress\": \"9256 Towne Center Dr., Suite 400\"," + 
                "  \"surname\": \"Gily\"," + 
                "  \"mobilePhone\": \"+91 02030713231\"," + 
                "  \"usageLocation\": \"IND\"," + 
                "  \"userPrincipalName\": \"adamg@alandonaldgmail.onmicrosoft.com\"}";

        System.out.println("Input: " + jsonInputData);
        URL url = new URL("https://graph.microsoft.com/v1.0/users");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "Bearer " + accessToken);
        System.out.println("Access Token: \n" + accessToken);
        System.out.println();
        conn.setRequestProperty("Content-type","application/json; charset=UTF-8");

        OutputStream os = conn.getOutputStream();
        os.write(jsonInputData.getBytes("UTF-8"));
        os.close();
        //display what returns the POST request

        StringBuilder sb = new StringBuilder();  
        int HttpResult = conn.getResponseCode();
        System.out.println("Response code: " + HttpResult);
        if (HttpResult == HttpURLConnection.HTTP_OK) {
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line = null;  
            while ((line = br.readLine()) != null) {  
                sb.append(line + "\n");  
            }
            br.close();
            System.out.println("" + sb.toString());  
        } else {
            System.out.println(conn.getResponseMessage());  
        }
        return null;
    }
}

所以这里我得到的错误代码为 400,错误消息为 'Bad request'。谁能给我解释一下这是什么问题?

错误请求问题通常与发送的一些无效 data/formatting 有关。

看看您的 json,有两点很突出。请进行这些更改,看看是否能解决您的问题。

  1. "userPrincipalName": "adamg@alandonaldgmail.onmicrosoft.com"(确保 alandonaldgmail.onmicrosoft.com 是您的 Azure Active Directory 组织的经过验证的域,如果不是并且您误用了它,然后将 userPrincipalName 的值更改为 "adamg@yourazureadtenantname.onmicrosoft.com")

  2. "usageLocation": "IND"(这应该只是 "IN",因为它应该是两个字母的国家代码(ISO 标准 3166))

从这里引用这些 - Update User API Reference

好的,所以我用 HttpClient 库实现了它。下面是相同的代码:

int count = 1;
String jsonInputData = "{ "+
                "  \"accountEnabled\": true," + 
                "  \"displayName\": \"TestUserFromEclipse" +count+"\"," + 
                "  \"mailNickname\": \"mailNickname-value\"," +
                "  \"country\": \"IN\"," +
                "  \"userPrincipalName\": \"eclipseuser"+count+"@alandonaldgmail.onmicrosoft.com\"," + 
                "  \"passwordProfile\" : {" + 
                "    \"forceChangePasswordNextSignIn\": false," + 
                "    \"password\": \"Sigma@123\"" + 
                "  }" + 
                "}";

    HttpPost post = null;
        try {
            String url = "https://graph.microsoft.com/v1.0/users";
            StringEntity s = new StringEntity(jsonInputData);
            HttpClient client = HttpClientBuilder.create().build();
            post = new HttpPost(url);

            // add header
            post.setHeader("Content-Type", "application/json");
            post.setHeader("Authorization", "Bearer " + accessToken);
            post.setEntity(s);

            HttpResponse response = client.execute(post);
            System.out.println("Response Code : " 
                        + response.getStatusLine().getStatusCode());
        } finally {
            post.releaseConnection();
        }