Утилітні функції 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 у вашому tenant.
У лівій панелі натисніть мітку Azure Active Directory. Це відкриє панель Azure Active Directory. На цьому екрані має бути мітка App registrations. Це стартова точка реєстрації застосунку Azure AD. Ця панель дозволяє створити новий застосунок для Azure AD.
Натисніть кнопку New registration, щоб створити новий застосунок.

3. Тепер ви побачите нову панель реєстрації застосунку.
- Name Це буде назва вашого застосунку.
- Supported account types Цей розділ обмежує доступ.
Натисніть кнопку Register.

4. Ви повинні бачити панель новостворених застосунків.
- Application (client) ID Ідентифікатор вашого застосунку.
- Directory (tenant) ID Ідентифікатор tenant 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. Тепер ви бачите список доступних дозволів для API Microsoft Graph.
Виберіть потрібні дозволи, натисніть кнопку Add permissions.
Натисніть кнопку Grant admin consent.

6. Дозволити потоки публічних клієнтів.
Визначає, чи є застосунок публічним клієнтом. Підходить для додатків, які використовують потоки видачі токенів без redirect 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();
}
}