Microsoft Graph उपयोगिता सुविधाएँ

Azure Active Directory एडमिन सेंटर में प्रोजेक्ट बनाना

एक प्रोजेक्ट Azure Active Directory एडमिन सेंटर में उस उपयोगकर्ता के लिए बनाया जाना है जिसके पास MS Office खाता है।

Azure Active Directory एडमिन सेंटर में प्रोजेक्ट बनाने के चरण

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 बटन पर क्लिक करें ताकि एक नया एप्लिकेशन बनाया जा सके।

todo:image_alt_text

3. अब आप नया एप्लिकेशन रजिस्ट्रेशन ब्लेड देखेंगे।

  • Name यह आपके एप्लिकेशन का नाम होगा।
  • Supported account types यह सेक्शन एक्सेस को प्रतिबंधित करेगा।

Register बटन पर क्लिक करें।

todo:image_alt_text

4. आपको नया पंजीकृत एप्लिकेशन ब्लेड दिखना चाहिए।

  • Application (client) ID आपके एप्लिकेशन का ID।
  • Directory (tenant) ID Azure AD टेनेन्ट ID।

todo:image_alt_text

5. Microsoft Graph API के लिए अनुमतियों को अनुमति देना।

API permissions लेबल पर क्लिक करें।

Azure ने पहले ही आपके एप्लिकेशन को User.Read डेलीगेटेड अनुमतियाँ दे दी हैं। यह अनुमति हमें लॉगिन किए हुए उपयोगकर्ता की जानकारी पढ़ने की अनुमति देती है। ये Microsoft Graph API की अनुमतियाँ हैं, जिन्हें हम 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 बटन पर क्लिक करें।

todo:image_alt_text

6. पब्लिक क्लाइंट फ्लो की अनुमति दें।

निर्दिष्ट करता है कि एप्लिकेशन पब्लिक क्लाइंट है या नहीं। उन ऐप्स के लिए उपयुक्त जो टोकन ग्रांट फ्लो का उपयोग करते हैं और रीडायरेक्ट URI नहीं इस्तेमाल करते।

todo:image_alt_text

7. एप्लिकेशन के लिए एक कुंजी बनाएं

todo:image_alt_text

हेल्पर क्लासेज

इस सेक्शन में कोड चलाने के लिए निम्नलिखित हेल्पर क्लासेज आवश्यक हैं। ये क्लासेज केवल प्रदर्शनी को सरल बनाने के लिए हैं।

AzureROPCTokenProvider क्लास

का एक इंस्टेंस IGraphClient क्लास अनुरोधों का निर्माण, उन्हें Microsoft Graph API को भेजने और प्रतिक्रियाओं को प्रोसेस करने को संभालती है। इस क्लास का नया इंस्टेंस बनाने के लिए, आपको इसका एक इंस्टेंस प्रदान करना होगा 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();
    }
}