תכונות שימושיות של Microsoft Graph

יצירת פרויקט במרכז ניהול Azure Active Directory

פרויקט צריך להיווצר במרכז ניהול Azure Active Directory עבור משתמש בעל חשבון MS Office.

צעדים ליצירת פרויקט במרכז ניהול Azure Active Directory

להלן מדריך צעד‑אחר‑צעד ליצירת פרויקט במרכז ניהול Azure Active Directory.

1. עבור ל-Azure Active Directory והתחבר באמצעות פרטי ה-MSO שלך.

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 ליצירת אפליקציה חדשה.

todo:image_alt_text

3. כעת תראה את לוח הרישום של האפליקציה החדשה.

  • Name זה יהיה שם האפליקציה שלך.
  • סוגי חשבונות נתמכים חלק זה יגביל את הגישה.

לחץ על כפתור Register.

todo:image_alt_text

4. עליך לראות את הלוח של האפליקציות שנרשמו לאחרונה.

  • Application (client) ID מזהה האפליקציה שלך.
  • Directory (tenant) ID מזהה השוכר של Azure AD.

todo:image_alt_text

5. מתן הרשאות ל-API של Microsoft Graph.

לחץ על תגית API permissions.

ל-Azure כבר ניתנו לך הרשאות User.Read מועדפות עבור האפליקציה שלך. הרשאה זו תאפשר לנו לקרוא מידע על משתמש מחובר. אלו הן הרשאות של API של Microsoft Graph, ובצד השני אפשר לכנותן Scopes.

הרשימה המלאה של סקופים ל-API של Microsoft Graph - https://docs.microsoft.com/en-us/graph/permissions-reference.

לחץ על כפתור + Add a permission ובחר Microsoft Graph.

לחץ על Delegated permissions. כעת אתה רואה רשימת הרשאות זמינות ל-API של Microsoft Graph.

בחר את ההרשאות הדרושות, לחץ על כפתור Add permissions.

לחץ על כפתור Grant admin consent.

todo:image_alt_text

6. אפשר זרימות של לקוח ציבורי.

מציין האם האפליקציה היא לקוח ציבורי. מתאים לאפליקציות המשתמשות בזרימות הענקת אסימונים שאינן משתמשות ב-Redirect URI.

todo:image_alt_text

7. יצירת מפתח עבור האפליקציה

todo:image_alt_text

מחלקות מסייעות

המחלקות העוזרות הבאות נדרשות להרצת הקוד בחלק זה. מחלקות אלה נועדו לפשט את ההדגמה בלבד.

מחלקת 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();
    }
}