【问题标题】:Getting 400 Bad request when sending POST request to Azure Graph API向 Azure Graph API 发送 POST 请求时收到 400 Bad request
【发布时间】:2018-09-20 15:40:25
【问题描述】:

我正在尝试向 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,错误消息为“错误请求”。谁能解释一下是什么问题?

【问题讨论】:

    标签: java azure azure-active-directory adal adal4j


    【解决方案1】:

    错误请求问题通常与正在发送的一些无效数据/格式有关。

    查看您的 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

    【讨论】:

    • 谢谢 Rohit,它有帮助。我尝试使用以下 json 数据通过代码创建用户,但是它给了我 400 错误请求,但我可以看到用户正在 Azure AD 中创建,你能告诉我应该是什么原因吗?我的 json 数据是:{ "accountEnabled": true, "displayName": "displayName-value", "mailNickname": "mailNickname-value", "userPrincipalName": "adamsg@alandonaldgmail.onmicrosoft.com", "passwordProfile" : { "forceChangePasswordNextSignIn": false, "password": "Sigma@123" } }
    • 好的,这次您使用的 json 负载要小得多。我确实在最后使用相同的 json 进行了快速尝试(仅更改 userprincipalname 以适用于我的组织)并且它工作正常。 2 件事要检查: 1. 如果是 400,您应该收到某种错误消息,尝试查看错误是什么 2. 快速猜测一下,我希望您不要尝试创建相同的 UserPrincipalName一次,因为第二次以后它会给你 400 错误“ObjectConflict”代码。
    • 是的,这里有一些事情: 1. 错误消息是“错误请求”,错误代码是 400 2. 是的,我给出了不同的 UserPrincipalName(不存在)
    • 你认为下面的代码有问题吗: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); conn.setRequestProperty("Content-Type","application/json"); OutputStream os = conn.getOutputStream(); os.write(jsonInputData.getBytes("UTF-8"));
    • @AmitG 是 AlanDonaldgmail.onmicrosoft.com 的 Azure AD 验证域吗?
    【解决方案2】:

    好的,所以我用 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();
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      • 1970-01-01
      • 2016-05-18
      • 1970-01-01
      • 2019-10-22
      • 1970-01-01
      • 2022-01-11
      相关资源
      最近更新 更多