Возможности утилиты Microsoft Graph
Создание проекта в Azure Active Directory Admin Center
Проект создается в центре администрирования Azure Active Directory для пользователя с учетной записью MS Office.
Шаги по созданию проекта в Azure Active Directory Admin Center
Ниже пошаговый учебник по созданию проекта в центре администрирования Azure Active Directory.
1. Перейдите в Azure Active Directory и войдите, используя учетные данные MS Office.
Azure Active Directory Ссылка - https://aad.portal.azure.com/
2. Создать приложение Azure AD в вашем арендаторе.
В левой панели нажмите метку Azure Active Directory. Откроется панель Azure Active Directory. На этом экране вы увидите метку App registrations. Это отправная точка регистрации приложения Azure AD. Эта панель позволит вам создать новое приложение для Azure AD.
Нажмите кнопку New registration, чтобы создать новое приложение.

3. Теперь вы увидите панель регистрации нового приложения.
- Name Это будет имя вашего приложения.
- Поддерживаемые типы учетных записей Этот раздел будет ограничивать доступ.
Нажмите кнопку Register.

4. Вы должны увидеть панель недавно зарегистрированных приложений.
- Application (client) ID Идентификатор вашего приложения.
- Directory (tenant) ID Идентификатор арендатора Azure AD.

5. Предоставление разрешений для Microsoft Graph API.
Нажмите на метку API permissions.
Azure уже предоставил вашему приложению делегированные разрешения User.Read. Это разрешение позволяет читать информацию о пользователе, вошедшем в систему. Это разрешения Microsoft Graph API, иначе их называют Scopes.
Полный список областей (scopes) для Microsoft Graph API - https://docs.microsoft.com/en-us/graph/permissions-reference.
Нажмите кнопку + Add a permission и выберите Microsoft Graph.
Кликните по Delegated permissions. Теперь вы видите список доступных разрешений для Microsoft Graph API.
Выберите необходимые разрешения, нажмите кнопку Add permissions.
Нажмите кнопку Grant admin consent.

6. Разрешить потоки публичного клиента.
Указывает, является ли приложение публичным клиентом. Подходит для приложений, использующих потоки выдачи токенов без URI перенаправления.

7. Создать ключ для приложения

Вспомогательные классы
Для выполнения кода в этом разделе требуются следующие вспомогательные классы. Эти классы предназначены только для упрощения демонстрации.
Класс AzureROPCTokenProvider
Экземпляр IGraphClient класс обрабатывает построение запросов, их отправку в API Microsoft Graph и обработку ответов. Чтобы создать новый экземпляр этого класса, необходимо предоставить экземпляр ITokenProvider, которые могут аутентифицировать запросы к Microsoft Graph.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
/**
* <p>
* Azure resource owner password credential (ROPC) token provider
* https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc
* https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth
* https://portal.azure.com
* https://developer.microsoft.com/en-us/graph/graph-explorer/#
* token parser https://jwt.io
* </p>
*/
class AzureROPCTokenProvider implements ITokenProvider {
private static final String GRANT_TYPE = "password";
private final String clientId;
private final String clientSecret;
private final String userName;
private final String password;
private final String tenant;
private final String scope;
private OAuthToken token;
public AzureROPCTokenProvider(String tenant, String clientId, String clientSecret,
String userName, String password, String[] scopeAr) {
this.tenant = tenant;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.userName = userName;
this.password = password;
this.scope = joinToStr(scopeAr, " ");
}
public synchronized OAuthToken getAccessToken(boolean ignoreExistingToken) {
if (this.token != null && !this.token.getExpired() && !ignoreExistingToken)
return this.token;
token = null;
Map<String, String> tokenArgs = geToken();
java.util.Calendar c = java.util.Calendar.getInstance();
c.add(java.util.Calendar.SECOND, Integer.parseInt(tokenArgs.get("expires_in")));
token = new OAuthToken(tokenArgs.get("access_token"), TokenType.AccessToken, c.getTime());
return token;
}
public final OAuthToken getAccessToken() {
return getAccessToken(false);
}
public void dispose() {
}
private String getEncodedParameters() {
return "client_id=" + urlEncode(clientId) + "&scope=" + urlEncode(scope) + "&username=" + urlEncode(userName)
+ "&password=" + urlEncode(password) + "&grant_type="
+ urlEncode(GRANT_TYPE);
}
private String getUri() {
if (tenant == null || tenant.trim().isEmpty())
return "https://login.microsoftonline.com/common/oauth2/v2.0/token";
else
return "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token";
}
private Map<String, String> geToken() {
try {
HttpURLConnection connection = (HttpURLConnection) new URL(getUri()).openConnection();
connection.setRequestMethod("POST");
byte[] requestData = getEncodedParameters().getBytes(StandardCharsets.UTF_8);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", "" + requestData.length);
final OutputStream st = connection.getOutputStream();
try {
st.write(requestData, 0, requestData.length);
} finally {
st.flush();
st.close();
}
connection.connect();
if (connection.getResponseCode() >= HttpURLConnection.HTTP_BAD_REQUEST) {
throw new IllegalAccessError("Operation failed: " + connection.getResponseCode() + "/" +
connection.getResponseMessage() + "\r\nDetails:\r\n{2}"
+ readInputStream(connection.getErrorStream()));
}
String responseText = readInputStream(connection.getInputStream());
Map<String, String> result = new HashMap<>();
String[] fromJsonToKeyValue = responseText.replace("{", "").replace("}", "")
.replace("\"", "").replace("\r", "")
.replace("\n", "").split(",");
for (String keyValue : fromJsonToKeyValue) {
String[] pair = keyValue.split(":");
String name = pair[0].trim().toLowerCase();
String value = urlDecode(pair[1].trim());
result.put(name, value);
}
return result;
} catch (IOException e) {
throw new IllegalAccessError(e.getMessage());
}
}
static String urlEncode(String value) {
try {
return URLEncoder.encode(value, StandardCharsets.UTF_8.toString());
} catch (UnsupportedEncodingException e) {
throw new IllegalAccessError(e.getMessage());
}
}
static String urlDecode(String value) {
try {
return URLDecoder.decode(value, StandardCharsets.UTF_8.toString());
} catch (UnsupportedEncodingException e) {
throw new IllegalAccessError(e.getMessage());
}
}
static String readInputStream(InputStream is) {
if (is == null)
return "";
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder result = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
result.append(line);
}
} catch (IOException e) {
// ignore
}
return result.toString();
}
static String joinToStr(String[] arr, String sep) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (i > 0)
sb.append(sep);
sb.append(arr[i]);
}
return sb.toString();
}
}