Recursos Utilitários do Microsoft Graph

Criando Projeto no Azure Active Directory Admin Center

Um Projeto deve ser criado no centro de administração do Azure Active Directory para um usuário com conta MS Office.

Etapas para Criar um Projeto no Azure Active Directory Admin Center

A seguir, um tutorial passo a passo para criar um projeto no centro de administração do Azure Active Directory.

1. Acesse o Azure Active Directory e faça login usando suas credenciais do MS Office.

Azure Active Directory Link - https://aad.portal.azure.com/

2. Criar um Aplicativo Azure AD no seu locatário.

No painel à esquerda, clique no rótulo Azure Active Directory. Isso abrirá o painel do Azure Active Directory. Nessa tela, você deverá ver o rótulo App registrations. Este é o ponto de partida para registrar um Aplicativo Azure AD. Este painel permitirá criar um novo aplicativo para Azure AD.

Clique no botão New registration para criar um novo aplicativo.

todo:image_alt_text

3. Agora você verá o painel de registro de novo aplicativo.

  • Name Este será o nome do seu aplicativo.
  • Supported account types Esta seção restringirá o acesso.

Clique no botão Register.

todo:image_alt_text

4. Você deverá ver o painel de aplicativos recém‑registrados.

  • Application (client) ID O ID do seu aplicativo.
  • Directory (tenant) ID O ID do locatário do Azure AD.

todo:image_alt_text

5. Concessão de permissões para a API Microsoft Graph.

Clique no rótulo API permissions.

O Azure já concedeu a você permissões delegadas User.Read para seu aplicativo. Essa permissão nos permite ler informações do usuário logado. Estas são permissões da API Microsoft Graph, por outro lado podemos chamá‑las de Escopos.

A lista completa de escopos para a API Microsoft Graph - https://docs.microsoft.com/en-us/graph/permissions-reference.

Clique no botão + Add a permission e selecione Microsoft Graph.

Clique em Delegated permissions. Agora você vê uma lista de permissões disponíveis para a API Microsoft Graph.

Selecione as permissões necessárias, clique no botão Add permissions.

Clique no botão Grant admin consent.

todo:image_alt_text

6. Permitir fluxos de cliente público.

Especifica se o aplicativo é um cliente público. Apropriado para aplicativos que utilizam fluxos de concessão de token que não usam um URI de redirecionamento.

todo:image_alt_text

7. Criar uma chave para o aplicativo

todo:image_alt_text

Classes Auxiliares

As classes auxiliares a seguir são necessárias para executar os códigos nesta seção. Estas classes são apenas para simplificação da demonstração.

Classe AzureROPCTokenProvider

Uma instância da IGraphClient a classe lida com a construção de solicitações, enviando-as para a API Microsoft Graph e processando as respostas. Para criar uma nova instância desta classe, você precisa fornecer uma instância de ITokenProvider, que pode autenticar solicitações ao 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();
    }
}