API Microsoft Graph возвращает valid_role_scope_combination при попытке получить фотографию профиля

Мне нужно получить фотографии профиля из API MS Graph и загрузить их в хранилище BLOB-объектов Azure.

Я делаю это с помощью MS Graph Java SDK. Вот код для получения фотографии InputStream:

InputStream photoInputStream = graphServiceClient.users().byUserId(adUser.getId()).photo().content().get();

Когда этот вызов сделан, я получаю следующее исключение:

com.microsoft.graph.models.odataerrors.ODataError: invalid_role_scope_combination
    at com.microsoft.graph.models.odataerrors.ODataError.createFromDiscriminatorValue(ODataError.java:36) ~[microsoft-graph-6.4.0.jar:na]
    at com.microsoft.kiota.serialization.JsonParseNode.getObjectValue(JsonParseNode.java:210) ~[microsoft-kiota-serialization-json-1.0.4.jar:na]
    at com.microsoft.kiota.http.OkHttpRequestAdapter.lambda$throwIfFailedResponse$0(OkHttpRequestAdapter.java:672) ~[microsoft-kiota-http-okHttp-1.0.4.jar:na]
    at com.microsoft.kiota.ApiExceptionBuilder.<init>(ApiExceptionBuilder.java:26) ~[microsoft-kiota-abstractions-1.0.4.jar:na]
    at com.microsoft.kiota.http.OkHttpRequestAdapter.throwIfFailedResponse(OkHttpRequestAdapter.java:671) ~[microsoft-kiota-http-okHttp-1.0.4.jar:na]
    at com.microsoft.kiota.http.OkHttpRequestAdapter.sendPrimitive(OkHttpRequestAdapter.java:341) ~[microsoft-kiota-http-okHttp-1.0.4.jar:na]
    at com.microsoft.graph.users.item.photo.value.ContentRequestBuilder.get(ContentRequestBuilder.java:60) ~[microsoft-graph-6.4.0.jar:na]
    at com.microsoft.graph.users.item.photo.value.ContentRequestBuilder.get(ContentRequestBuilder.java:46) ~[microsoft-graph-6.4.0.jar:na]
...

Я добавил следующие разрешения для регистрации приложения:

Вот код для настройки учетных данных MS Graph API, если это поможет:

private static final String DEFAULT_MS_GRAPH_SCOPE = "https://graph.microsoft.com/.default";

@Bean
public GraphServiceClient graphServiceClient() {
    ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
            .clientId(clientId)
            .clientSecret(clientSecret)
            .tenantId(tenantId)
            .build();

    return new GraphServiceClient(clientSecretCredential, DEFAULT_MS_GRAPH_SCOPE);
}

Не могли бы вы указать, что API permissions вы предоставили при регистрации приложения, отредактировав свой вопрос с помощью изображения портала?

Sridevi 25.03.2024 09:37

Добавил картинку с разрешения.

Herman Shpryhau 25.03.2024 10:48

Вы используете поток учетных данных клиента в коде, но предоставили разрешения делегированного типа. Не могли бы вы предоставить User.Read.All или User.ReadBasic.All разрешение типа «Приложение» и проверить, работает ли оно?

Sridevi 25.03.2024 10:51

Не могли бы вы проверить, можете ли вы получить фотографию профиля этого пользователя через Graph Explorer или нет, как это i.imgur.com/9famZjK.png?

Sridevi 26.03.2024 10:18
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
234
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я зарегистрировал одно приложение Azure AD и предоставил User.ReadBasic.All разрешение типа приложения, как показано ниже:

Чтобы получить изображение профиля пользователя и загрузить его в хранилище BLOB-объектов Azure, вы можете использовать приведенный ниже модифицированный Java-код:

import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.microsoft.graph.authentication.TokenCredentialAuthProvider;
import com.microsoft.graph.models.User;
import com.microsoft.graph.requests.GraphServiceClient;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

import com.azure.storage.blob.BlobClient;
import com.azure.storage.blob.BlobClientBuilder;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobContainerClientBuilder;

public class AzureADUserAuth {
    final String clientId = "appId";
    final String tenantId = "tenantId";
    final String clientSecret = "secret";
    final List<String> scopes = Arrays.asList("https://graph.microsoft.com/.default");

    // Azure Blob Storage settings
    final String connectionString = "storacc_connection_string";
    final String containerName = "profile-photos"; // Name of your blob container

    public static void main(String[] args) {
        try {
            AzureADUserAuth azureADUserAuth = new AzureADUserAuth();
            azureADUserAuth.fetchAndUploadProfilePhoto();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void fetchAndUploadProfilePhoto() throws Exception {
        // Authenticate with Azure AD
        ClientSecretCredential credential = new ClientSecretCredentialBuilder()
                .clientId(clientId).tenantId(tenantId).clientSecret(clientSecret)
                .build();

        if (null == scopes || null == credential) {
            throw new Exception("Unexpected error");
        }

        TokenCredentialAuthProvider authProvider = new TokenCredentialAuthProvider(scopes, credential);
        GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient();

        // Fetch user profile photo as InputStream
        InputStream profilePhotoStream = graphClient.users("userId")
                .photo()
                .content()
                .buildRequest()
                .get();

        // Read the profile photo content into a byte array
        byte[] photoBytes = profilePhotoStream.readAllBytes();

        // Create InputStream from byte array
        InputStream inputStream = new ByteArrayInputStream(photoBytes);

        // Upload profile photo to Azure Blob Storage
        BlobContainerClient containerClient = new BlobContainerClientBuilder()
                .connectionString(connectionString)
                .containerName(containerName)
                .buildClient();

        BlobClient blobClient = containerClient.getBlobClient("profile_photo.jpg");
        blobClient.upload(inputStream, photoBytes.length, true);

        // Close the InputStream when done
        profilePhotoStream.close();

        System.out.println("\nProfile photo uploaded to Azure Blob Storage.\n");
    }
}

Ответ:

Чтобы убедиться в этом, я проверил то же самое в контейнере больших двоичных объектов учетной записи хранения Azure, где фотография профиля была успешно загружена следующим образом:

Другие вопросы по теме