Azure AD Kurulumu ve Microsoft Graph Kimlik Doğrulaması

Aspose.Email for Java, Microsoft Graph ile tam entegrasyon sağlar; geliştiricilerin Microsoft 365 hesaplarından mesaj, kişi, takvim ve görevleri yönetmesine olanak tanır. Bu kılavuz, bir Azure AD uygulaması oluşturmanızı ve kimlik doğrulamayı yapılandırmanızı adım adım göstererek Aspose.Email ile kodlamaya başlamanızı sağlar. GraphClient.

Aspose.Email ile Microsoft Graph API’lerini kullanmadan önce, Azure Active Directory (Azure AD) içinde bir uygulama kaydetmeli ve kimlik doğrulamayı yapılandırmalısınız. Bu sayfa şunları kapsar:

  • Azure AD uygulaması (proje) oluşturma.

  • Gerekli Microsoft Graph izinlerini atama.

  • Kimlik bilgilerini (istemci kimliği, istemci gizli anahtarı, kiracı kimliği) oluşturma.

  • Aspose.Email token sağlayıcıları kullanarak Java’da kimlik doğrulama.

Tamamlandığında, Java uygulamanızdan Microsoft Graph ile etkileşime hazır olacaksınız.

1. Azure AD Uygulaması Oluşturun

Uygulamanızı Azure portalında kaydetmek için bu adımları izleyin:

  1. Şunun içinde oturum açın Azure portalı.
  2. Azure Active DirectoryApp RegistrationsNew Registration‘a gidin.

todo:image_alt_text

  1. Uygulamanız için bir Name (İsim) girin (örnek: AsposeEmailGraphApp).
  2. Desteklenen hesap türlerini seçin:
    • Tek kiracı (yalnızca kuruluşunuz kullanacaksa)
    • Çok kiracılı (birden fazla kuruluşun erişmesi gerektiğinde)
  3. İsteğe bağlı olarak bir Redirect URI ayarlayın (etkileşimli veya web kimlik doğrulama için gerekir).
  4. Register‘a tıklayın.

todo:image_alt_text

2. İstemci Gizli Anahtarı Oluşturun

  1. Kayıttan sonra Certificates & SecretsNew Client Secret‘a gidin.
  2. Bir açıklama ve son kullanım süresi ekleyin.

todo:image_alt_text

  1. Oluşturulan gizli değerini kopyalayın - bir daha göremezsiniz.

İstemci gizli anahtarını güvende tutun; gizli istemci kimlik doğrulaması için gereklidir.

Yeni kaydedilen uygulamalar bölmesini görmelisiniz.

todo:image_alt_text

3. Microsoft Graph İzinlerini Yapılandırma

  1. API PermissionsAdd a PermissionMicrosoft Graph‘a gidin.
  2. Senaryonuza bağlı olarak izin türünü seçin: Delegated (Delegeli) veya Application (Uygulama).
  3. Aspose.Email işlemleri için gereken izinleri ekleyin:
    • Contacts.ReadWrite – kişileri yönetmek için
    • Calendars.ReadWrite – takvimleri yönetmek için
    • Mail.ReadWrite – mesajları okumak ve göndermek için
    • Tasks.ReadWrite – görevleri yönetmek için
  4. Gerekirse Yönetici Onayı Ver’e tıklayın.

todo:image_alt_text

4. Genel istemci akışlarına izin ver

Uygulamanın genel bir istemci olup olmadığını belirtin. Yönlendirme URI’sı kullanmayan token verme akışları kullanan uygulamalar için uygundur.

todo:image_alt_text

5. Microsoft Graph Kimlik Doğrulaması

Aspose.Email’de Desteklenen Kimlik Doğrulama Yöntemleri

| Token Sağlayıcı | Kullanım Durumu | | ——————————– | ————————————————————————————— | | AzureConfidentialTokenProvider | Sunucu tarafı uygulamalar için gizli istemci (istemci kimliği + gizli anahtar) | | AzureROPCConfiguration | Etkileşimsiz senaryolar için Kaynak Sahibi Şifre Kimlik Bilgileri (kullanıcı adı + şifre) | | AzurePublicTokenProvider | Genel istemci (etkileşimli oturum açma) | | AzureTokenProviderBase | Özel kimlik doğrulama uygulamaları için temel sınıf |

Gizli Bir İstemci Kullanarak Kimlik Doğrulama

Kullan AzureConfidentialTokenProvider istemci kimliği, istemci gizli anahtarı ve kiracı kimliği olduğunda kimlik doğrulama için:

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");

Bu, Microsoft Graph ile etkileşime hazır tam olarak kimlik doğrulanmış bir IGraphClient oluşturur.

ROPC (Kullanıcı Adı ve Şifre) Kullanarak Kimlik Doğrulama

Kullanıcı adı ve şifreye sahip olduğunuz senaryolar için, şunu kullanın 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");

Microsoft Graph için Özel Token Sağlayıcıları

Aspose.Email for Java, Microsoft Graph ile şu aracılığıyla entegre olur IGraphClient arayüz. İstekleri kimlik doğrulamak için, şunun bir uygulamasını gerekir ITokenProvider gereklidir. Çoğu geliştirici yerleşik kimlik doğrulama sağlayıcılarını kullansa da, kendi sağlayıcınızı oluşturmak isteyebileceğiniz senaryolar vardır; örneğin Resource Owner Password Credentials (ROPC) akışıyla çalışırken.

1. AzureROPCTokenProvider kullanarak ITokenProvider’ı Uygulayın

Bu sınıf, şunun bir uygulamasını sağlar ITokenProvider Azure Resource Owner Password Credentials (ROPC) akışı kullanarak. Aşağıdaki örnek sadece gösterim amaçlıdır. Üretimde, istemci kimlik bilgileri veya PKCE ile yetkilendirme kodu gibi daha güvenli akışların kullanılmasını öneririz.

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. ITokenProvider Nesnesi Oluşturun

Bu IGraphClient arayüz, istekleri oluşturmak, Microsoft Graph’e göndermek ve yanıtları işlemekten sorumludur. Bir örnek oluşturmak için IGraphClient, şunun bir uygulamasını sağlamalısınız ITokenProvider. Token sağlayıcı, geçerli bir OAuth erişim belirteci sağlayarak istekleri kimlik doğrular.

Aşağıdaki kod örneği, temel bir satır içi uygulamasının nasıl oluşturulacağını gösterir: ITokenProvider arayüz, Microsoft Graph isteklerini yetkilendirmek için gereklidir:

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. Özel Token Sağlayıcıyı Kullanma

Bir kez ITokenProvider kuruldu, bir şey oluşturabilirsiniz GraphClient örnek. Bu istemci, Microsoft Graph çağrılarında kimlik doğrulama için sağlanan token sağlayıcıyı kullanacaktır.

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

İstemci oluşturulup kimlik doğrulaması yapıldıktan sonra, Microsoft Graph hizmetlerine istek göndermeye başlayabilirsiniz.