Azure AD‑configuratie en Microsoft Graph‑authenticatie

Aspose.Email for Java biedt volledige integratie met Microsoft Graph, waardoor ontwikkelaars berichten, contactpersonen, agenda’s en taken kunnen beheren vanuit Microsoft 365‑accounts. Deze handleiding leidt je door het maken van een Azure AD‑applicatie en het configureren van authenticatie om te beginnen met coderen met Aspose.Email GraphClient.

Voordat je Microsoft Graph‑API’s met Aspose.Email gebruikt, moet je een applicatie registreren in Azure Active Directory (Azure AD) en authenticatie configureren. Deze pagina behandelt:

  • Een Azure AD‑applicatie (project) aanmaken.

  • De benodigde Microsoft Graph‑rechten toewijzen.

  • Credenties genereren (client‑ID, client‑secret, tenant‑ID).

  • Authenticatie in Java met Aspose.Email‑tokenproviders.

Zodra het voltooid is, ben je klaar om met Microsoft Graph te communiceren vanuit je Java‑applicatie.

1. Maak een Azure AD-applicatie

Volg deze stappen om je applicatie te registreren in het Azure‑portaal:

  1. Meld je aan bij de Azure‑portaal.
  2. Navigeer naar Azure Active DirectoryApp RegistrationsNew Registration.

todo:image_alt_text

  1. Voer een Naam in voor je applicatie (bijv. AsposeEmailGraphApp).
  2. Kies ondersteunde accounttypen:
    • Single tenant (als alleen jouw organisatie het zal gebruiken)
    • Multitenant (als meerdere organisaties toegang nodig hebben)
  3. Optioneel kun je een Redirect URI instellen (nodig voor interactieve of web‑authenticatie).
  4. Klik op Register.

todo:image_alt_text

2. Maak een client secret

  1. Ga na de registratie naar Certificates & SecretsNew Client Secret.
  2. Voeg een beschrijving en vervaldatum toe.

todo:image_alt_text

  1. Kopieer de gegenereerde geheime waarde – je zult deze niet meer zien.

Bewaar het client secret veilig; het is vereist voor authenticatie van een confidential client.

Je zou het blad met nieuw geregistreerde applicaties moeten zien.

todo:image_alt_text

3. Configureer Microsoft Graph-rechten

  1. Navigeer naar API PermissionsAdd a PermissionMicrosoft Graph.
  2. Kies het type rechten: Delegated of Application, afhankelijk van je scenario.
  3. Voeg de toegestane rechten toe die nodig zijn voor Aspose.Email‑bewerkingen:
    • Contacts.ReadWrite – om contactpersonen te beheren
    • Calendars.ReadWrite – om agenda’s te beheren
    • Mail.ReadWrite – om berichten te lezen en te verzenden
    • Tasks.ReadWrite – om taken te beheren
  4. Klik op Grant Admin Consent indien nodig.

todo:image_alt_text

4. Sta publieke clientstroom toe

Geef aan of de applicatie een publieke client is. Geschikt voor apps die token‑grant‑stromen gebruiken die geen omleidings‑URI gebruiken.

todo:image_alt_text

5. Microsoft Graph-authenticatie

Ondersteunde authenticatiemethoden in Aspose.Email

| Tokenprovider | Gebruikssituatie | | ——————————– | ————————————————————————————— | | AzureConfidentialTokenProvider | Confidential client (client-ID + secret) voor server-side apps | | AzureROPCConfiguration | Resource Owner Password Credentials (gebruikersnaam + wachtwoord) voor niet-interactieve scenario’s | | AzurePublicTokenProvider | Publieke client (interactieve login) | | AzureTokenProviderBase | Basisklasse voor aangepaste authenticatie-implementaties |

Authenticeer met een Confidential Client

Gebruik de AzureConfidentialTokenProvider om te authenticeren wanneer je client-ID, client-secret en tenant-ID hebt:

AzureConfidentialTokenProvider provider = new AzureConfidentialTokenProvider(
    tenantId,
    clientId,
    clientSecret
);

IGraphClient client = GraphClient.getClient(provider, tenantId);
client.setResource(ResourceType.Users);
client.setResourceId(username);
client.setEndpoint("https://graph.microsoft.com");

Dit stelt een volledig geauthenticeerde IGraphClient in, klaar om te communiceren met Microsoft Graph.

Authenticeer met ROPC (Gebruikersnaam & Wachtwoord)

Voor scenario’s waarbij je een gebruikersnaam en wachtwoord hebt, gebruik AzureROPCConfiguration:

AzureROPCConfiguration ropcConfig = new AzureROPCConfiguration(
    tenantId,
    clientId,
    clientSecret,
    username,
    password
);

IGraphClient client = GraphClient.getClient(ropcConfig, tenantId);
client.setResource(ResourceType.Users);
client.setResourceId(username);
client.setEndpoint("https://graph.microsoft.com");

Aangepaste Token Providers voor Microsoft Graph

Aspose.Email for Java integreert met Microsoft Graph via de IGraphClient interface. Om verzoeken te authenticeren, een implementatie van de ITokenProvider is vereist. Hoewel de meeste ontwikkelaars ingebouwde authenticatieproviders gebruiken, zijn er scenario’s waarin je je eigen provider wilt maken, bijvoorbeeld bij het werken met de Resource Owner Password Credentials (ROPC)-stroom.

1. Implementeer ITokenProvider met AzureROPCTokenProvider

Deze klasse biedt een implementatie van ITokenProvider met behulp van de Azure Resource Owner Password Credentials (ROPC)-stroom. Het volgende voorbeeld is uitsluitend voor demonstratiedoeleinden. In productie raden we aan veiligere stromen te gebruiken, zoals client credentials of autorisatiecode met PKCE.

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 = getToken();

        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> getToken() {
        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();
    }
}

2. Maak een ITokenProvider-object

De IGraphClient interface is verantwoordelijk voor het opbouwen van verzoeken, ze naar Microsoft Graph te verzenden en de antwoorden af te handelen. Om een instantie van te maken IGraphClient, moet je een implementatie leveren van ITokenProvider. De tokenprovider authenticeert verzoeken door een geldige OAuth-toegangstoken te leveren.

Het volgende codevoorbeeld laat zien hoe je een basis inline-implementatie maakt van de ITokenProvider interface, die vereist is voor het authenticeren van Microsoft Graph-verzoeken:

ITokenProvider tokenProvider = new ITokenProvider() {
    Date expirationDate = null;

    @Override
    public void dispose() {
        // Clean up resources if necessary
    }

    @Override
    public OAuthToken getAccessToken(boolean ignoreExistingToken) {
        // Retrieve an OAuth access token.
        // If ignoreExistingToken is true, always request a new token.
        // Otherwise, return the existing token if it is valid, or request a new one.
        return null;
    }

    @Override
    public OAuthToken getAccessToken() {
        // Return a valid OAuth token.
        // If no valid token exists, request a new one.
        return new OAuthToken("token", expirationDate);
    }
};

3. Gebruik van de Aangepaste Token Provider

Zodra de ITokenProvider is ingesteld, kunt u een GraphClient instance. Deze client zal de meegeleverde token‑provider gebruiken voor authenticatie bij het aanroepen van Microsoft Graph.

ITokenProvider provider = new AzureROPCTokenProvider(
        tenantId,
        clientId,
        clientSecret,
        userName,
        password,
        new String[] {"https://graph.microsoft.com/.default"}
);

IGraphClient client = GraphClient.getClient(provider, tenantId);
client.setResource(ResourceType.Users);
client.setResourceId(userName);
client.setEndpoint("https://graph.microsoft.com");

// Now you can call Microsoft Graph APIs
var folders = client.listFolders(null);
for (GraphFolderInfo folder : folders) {
    System.out.println(folder.getDisplayName());
}

Nadat de client is aangemaakt en geauthenticeerd, kunt u verzoeken naar Microsoft Graph‑services doen.