Use Microsoft Graph with standard Java

Microsoft Graph in standard Java package

You can use the Microsoft SDK for Java, but it requires a lot of related Jar files. To understand what you're doing in essence, let's write a Microsoft Graph query with just a standard Java package.

What to do

  1. Register the application in Azure AD and create a client ID and secret (the procedure is Tutorial. reference)
  2. Get an access token from Azure AD with OAuth2. It will be returned in JSON.
  3. Contact the Microsoft Graph API endpoint. JSON is returned. only.

If you write it with the Curl command for the time being, it will be like this

Get an access token.

First, get an access token from Azure Active Directory according to the OAuth procedure. The URL (endpoint) to get is

** https://login.microsoftonline.com/tenant ID/oauth2/v2.0/token **

The tenant ID can be found in the Azure AD tenant overview. POST the client ID and secret created towards here. Since scope escapes the URL, it is% 3A or% 2F. For details on what can be specified, click here [https://docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-permissions-and-consent). grant_type is an OAuth parameter with a fixed value.

curl -d "client_id=Client ID" \
 -d "scope=https%3A%2F%2Fgraph.microsoft.com%2F.default" \
 -d "client_secret=Client secret" \
 -d "grant_type=client_credentials" \
 -H "Content-Type: application/x-www-form-urlencoded" \
 -X POST https://login.microsoftonline.com/Tenant ID/oauth2/v2.0/token

You can get an access token. image.png

Contact the Microsoft Graph API using an access token

Copy the previous access token and now query and manipulate the Microsoft Graph API. For example, if you want to get a group member, it will look like this. Click here for the endpoint.

https://graph.microsoft.com/v1.0/groups/{group-id}/members

Use Graph Explorer to check where the endpoint is and the format. I will omit it, but for the group ID, I logged in to Azure AD and obtained the ID displayed in the "All groups" list in advance.

curl -H GET 'https://graph.microsoft.com/v1.0/groups/Group ID/members'\
 -H 'Content-Type: application/json;charset=utf-8'\
 -H 'Authorization:Bearer access token'

I've omitted the screenshot of the result, but you can see that the value is returned in JSON format. image.png

If you write this HTTP process in Java

This time it is written in Java 8. Also, error handling is omitted. If the network is under a proxy, set the proxy settings using Java environment variables.

App.java


import java.io.*;
import java.net.*;

//Although it is said to be a standard package, I used the javax additional library only here.
//It also decodes Unicode escaped characters
//Click here for Jar file
//https://repo1.maven.org/maven2/org/glassfish/javax.json/1.1.4/javax.json-1.1.4.jar
import javax.json.*;

public class App {

	public static void main(String[] args) throws Exception {
		
		String tenant_id = "Tenant ID";
		String client_id = "Client ID";
		String client_secret = "Client secret";
		String group_id = "Group ID";
		
		HttpURLConnection conn = null;
		InputStream input = null;
		HttpURLConnection conn2 = null;
		InputStream input2 = null;
		try {
			//①
			//Get an access token with Oauth2
			
			//Java standard HTTP request processing
			URL url = new URL("https://login.microsoftonline.com/" + tenant_id + "/oauth2/v2.0/token");
			conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);//Time to connect millisecond
			conn.setReadTimeout(5000);//Time to read data milliseconds
			conn.setRequestMethod("POST");//HTTP method
			conn.setUseCaches(false);//Use cache
			conn.setDoOutput(true);//Allow sending of request body(False for GET,Set to true for POST)
			conn.setDoInput(true);//Allow receiving body of response
			conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			String data = //Data to post
				  "client_id=" + client_id
				+ "&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default"  //java.net.May be escaped with URLEncoder
				+ "&client_secret=" + client_secret
				+ "&grant_type=client_credentials";
			conn.getOutputStream().write(data.getBytes("utf-8"));
			conn.getOutputStream().close(); // send
			
			//Receive the result and convert it to a Json object
			//If you don't use the JSON library, just parse the returned text on your own
			//I'm getting something similar to the string I was getting with Curl
			int code = conn.getResponseCode();
			input = (code == 200 ? conn.getInputStream() : conn.getErrorStream());
			JsonReader jsonReader = Json.createReader(new BufferedReader(new InputStreamReader(input, "utf-8")));
			JsonObject json = jsonReader.readObject();
			jsonReader.close();
			conn.disconnect();
			
			//I got the access token!
			String access_token = json.getString("access_token");
			
			
			//②
			//Next, contact the Microsoft Graph API for group members
			URL url2 = new URL("https://graph.microsoft.com/v1.0/groups/" + group_id + "/members");
			conn2 = (HttpURLConnection) url2.openConnection();
			conn2.setConnectTimeout(5000);//Time to connect millisecond
			conn2.setReadTimeout(5000);//Time to read data milliseconds
			conn2.setRequestMethod("GET");
			conn2.setUseCaches(false);//Use cache
			conn2.setDoOutput(false);//Allow sending of request body(False for GET,Set to true for POST)
			conn2.setDoInput(true);//Allow receiving body of response
			conn2.setRequestProperty("Authorization", "Bearer " + access_token); //Obtained access token
			conn2.setRequestProperty("Accept", "application/json"); //This is important! !! !! The point I was addicted to
			conn2.connect();
		
			int code2 = conn2.getResponseCode();
			input2 = (code2 == 200 ? conn2.getInputStream() : conn2.getErrorStream());
			JsonReader jsonReader2 = Json.createReader(new BufferedReader(new InputStreamReader(input2, "utf-8")));
			JsonStructure json2 = jsonReader2.read();
			jsonReader2.close();
			conn2.disconnect();
		
			JsonArray members = json2.asJsonObject().getJsonArray("value");
			
			//I got a member of the group!
			System.out.println(members);
		}
		catch(Error e) {
			e.printStackTrace();
		}
		finally {
			if(input != null) try { input.close(); } catch(Exception e){}
			if(conn != null) try { conn.disconnect(); } catch(Exception e){}
			if(input2 != null) try { input2.close(); } catch(Exception e){}
			if(conn2 != null) try { conn2.disconnect(); } catch(Exception e){}
		}
	}
}

I got it properly when I compiled and executed it. image.png

Summary

Simple acquisition is possible without using the SDK, you can grasp the essence because you do not need multiple additional Jar files and the procedure with the server is not hidden. On the other hand, if you use the SDK, you can concentrate on coding without being aware of the token expiration or the URL of the endpoint, and Graph Explorer will output a code snippet, so I think that productivity will increase.

Recommended Posts

Use Microsoft Graph with standard Java
Use Lambda Layers with Java
Use SpatiaLite with Java / JDBC
Use java with MSYS and Cygwin
Use Azure Bing SpellCheck with Java
Use JDBC with Java and Scala.
Use Java 11 with Google Cloud Functions
[Java] Use cryptography in the standard library
[JaCoCo (Java Code Coverage)] Use with NetBeans
Java standard logger
[Java] Use Collectors.collectingAndThen
How to use Java framework with AWS Lambda! ??
I want to use java8 forEach with index
How to use Java API with lambda expression
Use Matplotlib from Java or Scala with Matplotlib4j
[JAVA] [Spring] [MyBatis] Use IN () with SQL Builder
Output simple graph with Rails Use gem-chartkick / groupdate
Install java with Homebrew
Use fast Mapping library MapStruct with Lombok and Java 11
Use ProGuard with Gradle
Change seats with java
java standard functional interface
[Java] How to encrypt with AES encryption with standard library
Use Puphpeteer with Docker
Use aggregate queries (Count) with Azure CosmosDB Java SDK
Comfortable download with JAVA
Use XVim2 with Xcode 12.0.1
Use CentOS with LXD
Play with Java function nodes that can use Java with Node-RED
Graph creation with JFreeChart
Hit graph query with Java + PGX at explosive speed
Switch java with direnv
Use OpenCV in Java
Use ngrok with Docker
Use webmock with Rspec
Download Java with Ansible
Let's scrape with Java! !!
Use java1.7 (zulu7) under a specific directory with jenv
Use WebJars with Gradle
Build Java with Wercker
Use PreparedStatement in Java
Use jlink with gradle
Endian conversion with JAVA
Code to use when you want to process Json with only standard library in Java
How to use trained model of tensorflow2.0 with Kotlin / Java
Use Java included with Android Studio to build React Native
[Java] I want to test standard input & standard output with JUnit
Easy BDD with (Java) Spectrum?
Java multi-project creation with Gradle
Getting Started with Java Collection
Use GDAL with Python with Docker
[Java] How to use Map
Java memo (standard class) substring
Java Config with Spring MVC
[Java] How to use Map
Basic Authentication with Java 11 HttpClient
Let's experiment with Java inlining
Run batch with docker-compose with Java batch
Rewrite Java try-catch with Optional
Install Java 7 with Homebrew (cask)
Introduced graph function with rails