Microsoft Graph‑verktygsfunktioner

Skapa projekt i Azure Active Directory Admin Center

Ett projekt ska skapas i Azure Active Directory‑admincenter för en användare med MS Office‑konto.

Steg för att skapa ett projekt i Azure Active Directory Admin Center

Följande är en steg‑för‑steg‑handledning för att skapa ett projekt i Azure Active Directory‑admincenter.

1. Gå till Azure Active Directory och logga in med dina MS Office‑uppgifter.

Azure Active Directory‑länk – https://aad.portal.azure.com/

2. Skapa en Azure AD‑applikation i din tenant.

I den vänstra panelen, klicka på etiketten Azure Active Directory. Detta öppnar bladet för Azure Active Directory. På den skärmen bör du se etiketten App registrations. Detta är startpunkten för att registrera en Azure AD‑applikation. Detta blad låter dig skapa en ny applikation för Azure AD.

Klicka på knappen New registration för att skapa en ny applikation.

todo:image_alt_text

3. Nu kommer du att se bladet för ny applikationsregistrering.

  • Name Detta blir namnet på din applikation.
  • Supported account types Detta avsnitt begränsar åtkomsten.

Klicka på knappen Register.

todo:image_alt_text

4. Du bör se bladet för nyregistrerade applikationer.

  • Application (client) ID ID för din applikation.
  • Directory (tenant) ID Azure AD‑tenant‑ID.

todo:image_alt_text

5. Tillåta behörigheter för Microsoft Graph‑API.

Klicka på etiketten API permissions.

Azure har redan gett dig User.Read‑delegationsbehörighet för din applikation. Denna behörighet gör att vi kan läsa användarinformation för en inloggad användare. Detta är Microsoft Graph‑API‑behörigheter, som vi även kan kalla Scopes.

Den fullständiga listan över scopes för Microsoft Graph‑API – https://docs.microsoft.com/en-us/graph/permissions-reference.

Klicka på knappen + Add a permission och välj Microsoft Graph.

Klicka på Delegated permissions. Nu ser du en lista med behörigheter som finns tillgängliga för Microsoft Graph‑API.

Välj nödvändiga behörigheter, klicka på knappen Add permissions.

Klicka på knappen Grant admin consent.

todo:image_alt_text

6. Tillåt publika klientflöden.

Anger om applikationen är en publik klient. Lämplig för appar som använder token‑grant‑flöden som inte använder en omdirigerings‑URI.

todo:image_alt_text

7. Skapa en nyckel för applikationen

todo:image_alt_text

Hjälparklasser

Följande hjälparklasser krävs för att köra koden i detta avsnitt. Dessa klasser finns endast för att förenkla demonstrationen.

AzureROPCTokenProvider‑klass

En instans av IGraphClient klassen hanterar att bygga förfrågningar, skicka dem till Microsoft Graph‑API:t och bearbeta svaren. För att skapa en ny instans av denna klass behöver du tillhandahålla en instans av ITokenProvider, som kan autentisera förfrågningar till 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();
    }
}