Java 带有图形API的MSAL

Java 带有图形API的MSAL,java,azure,azure-active-directory,microsoft-graph-api,msal,Java,Azure,Azure Active Directory,Microsoft Graph Api,Msal,我试图构建一个Java代码,使用MSAL和MS Graph API在AAD中创建用户。下面是我用来创建用户的代码。我能够成功地检索令牌,但是在尝试发布请求时遇到异常。我做错了什么 public static void main(String[] args) throws Exception { Map<String,Object> params = new LinkedHashMap<>(); params.put(&quo

我试图构建一个Java代码,使用MSAL和MS Graph API在AAD中创建用户。下面是我用来创建用户的代码。我能够成功地检索令牌,但是在尝试发布请求时遇到异常。我做错了什么

public static void main(String[] args) throws Exception {
         Map<String,Object> params = new LinkedHashMap<>();      
         params.put("givenName", "Test");
         params.put("displayName", "ABC");
         params.put("accountEnabled", true);
         params.put("mailNickname","abc");
         params.put("userPrincipalName","jcooper@demo.onmicrosoft.com");    
         StringBuilder postData = new StringBuilder();
         for (Map.Entry<String,Object> param : params.entrySet()) {
             if (postData.length() != 0) postData.append('&');
             postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
             postData.append('=');
             postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
         }
         byte[] postDataBytes = postData.toString().getBytes("UTF-8");
int length =postDataBytes.length;
        URL url = new URL("https://graph.microsoft.com/v1.0/users");
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
      conn.setRequestMethod("POST");
      conn.setRequestProperty("Content-Type","application/json");
      conn.setRequestProperty("Authorization", "Bearer "+accessToken);
      conn.setDoInput(true);
      conn.setDoOutput(true);
      conn.setInstanceFollowRedirects(false);
       conn.setRequestProperty("Content-Length",Integer.toString(length));
        conn.connect();      
        conn.getInputStream();
        try (var wr = new DataOutputStream(conn.getOutputStream())) {
            wr.write(postDataBytes);
        }
        StringBuilder content;     
        System.out.println(postDataBytes+" "+postData);
        try (var br = new BufferedReader(
                new InputStreamReader(conn.getInputStream()))) {
            String line;
            content = new StringBuilder();
            while ((line = br.readLine()) != null) {
                content.append(line);
                content.append(System.lineSeparator());
            }
       }
        System.out.println(content.toString());
    }   
publicstaticvoidmain(字符串[]args)引发异常{
Map params=新建LinkedHashMap();
参数put(“givenName”、“Test”);
参数put(“显示名称”、“ABC”);
参数put(“accountEnabled”,true);
参数put(“邮件昵称”、“abc”);
参数put(“userPrincipalName”jcooper@demo.onmicrosoft.com");    
StringBuilder postData=新建StringBuilder();
对于(Map.Entry参数:params.entrySet()){
如果(postData.length()!=0)postData.append('&');
append(URLEncoder.encode(param.getKey(),“UTF-8”);
postData.append('=');
append(URLEncoder.encode(String.valueOf(param.getValue()),“UTF-8”);
}
字节[]postDataBytes=postData.toString().getBytes(“UTF-8”);
int length=postDataBytes.length;
URL=新URL(“https://graph.microsoft.com/v1.0/users");
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setRequestMethod(“POST”);
conn.setRequestProperty(“内容类型”、“应用程序/json”);
conn.setRequestProperty(“授权”、“承载人”+accessToken);
conn.setDoInput(真);
连接设置输出(真);
conn.setInstanceFollow(假);
conn.setRequestProperty(“内容长度”,Integer.toString(长度));
连接();
conn.getInputStream();
try(var wr=newdataoutputstream(conn.getOutputStream())){
wr.write(postDataBytes);
}
StringBuilder内容;
System.out.println(postDataBytes+“”+postData);
try(var br=new BufferedReader(
新的InputStreamReader(conn.getInputStream())){
弦线;
内容=新的StringBuilder();
而((line=br.readLine())!=null){
内容。追加(行);
content.append(System.lineSeparator());
}
}
System.out.println(content.toString());
}   

异常:线程“main”java.io.IOException中的异常异常异常:服务器返回了URL的HTTP响应代码:411:

根据一些测试,我遇到了与您相同的问题。代码似乎是正确的,但不知道为什么仍然显示411错误。这可能是因为graph api只能接受json请求体,但在第一部分代码中将请求体转换为
application/x-www-form-urlencoded
(我不确定,因为我使用json请求体测试代码,但仍然显示411)

因为您提到了使用MSAL获取访问令牌,所以您还可以继续使用MSAL创建用户。请参阅:


要从桌面应用程序访问Microsoft Graph,我将使用
InteractiveBrowserCredentialBuilder()
和GraphSDK附带的
TokenCredentialAuthProvider
来获取Graph令牌。看看这部伟大的电影。要定制它,您只需更改最后一行,并根据需要调用的Graph API设置不同的作用域。该页面底部有一个链接,教你如何正确注册应用程序


web应用程序中最简单的方法是使用Azure AD Spring Boot Starter为登录用户获取访问令牌,并在Spring 5 web应用程序中使用GraphSDK调用Graph。请参见演示此过程的完整说明(相关图形代码位于SampleController.java和Utilities.java中)

(1)如果您使用MSAL for java,则可以启用跟踪/内置遥测日志记录,以查看您在哪个API调用中看到问题。(2) 分享您得到的一个问题的详细错误/跟踪…哪种方法应该是首选方法,使用MSAL或graphClient作为访问令牌?@SushmitaDas我很抱歉没有清楚地描述解决方案。如果使用MSAL,则不需要在代码中获取访问令牌。您可以从中选择身份验证提供程序,例如“客户端凭据提供程序”。然后继续使用我在上面提供的MSAL代码来创建用户。我需要您的帮助来理解您提供的参考链接与我提供的参考链接之间的差异。后者使用MSAL获取访问令牌,前者使用客户端凭据流作为身份验证提供者。两者的区别是什么?“推荐哪一种?”SushmitaDas很抱歉延迟回复。它们都可以实现需求,并且在后端几乎相同。区别在于我提供的第一个示例没有在代码中获得访问令牌。但是实际上
graphClient
中已经包含了访问令牌,因此它可以执行get/create用户操作。您提供的第二个链接在代码中获取访问令牌,然后使用HTTP请求执行相同的操作(get/create user)。Hi@SushmitaDas关于此帖子的任何更新或任何其他问题?如果没有其他问题,请您将答案标记为“已接受”,谢谢。
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();

User user = new User();
user.accountEnabled = true;
user.displayName = "Adele Vance";
user.mailNickname = "AdeleV";
user.userPrincipalName = "AdeleV@contoso.onmicrosoft.com";
PasswordProfile passwordProfile = new PasswordProfile();
passwordProfile.forceChangePasswordNextSignIn = true;
passwordProfile.password = "xWwvJ]6NMw+bWH-d";
user.passwordProfile = passwordProfile;

graphClient.users()
    .buildRequest()
    .post(user);