I need to get profile photos from MS Graph API and upload them to Azure Blob storage.
I am doing this with MS Graph Java SDK. Here us the code for retrieving the photo InputStream
:
InputStream photoInputStream = graphServiceClient.users().byUserId(adUser.getId()).photo().content().get();
When this call is made, I get the following exception:
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]
...
I have added the following permissions to application registration:
Here is the code for configuring MS Graph API credentials if this helps:
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);
}
I registered one Azure AD application and granted User.ReadBasic.All
permission of Application type as below:
To retrieve the profile image of user and upload it to Azure blob storage, you can make use of below modified java code:
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");
}
}
Response:
To confirm that, I checked the same in Azure Storage account blob container where profile photo uploaded successfully like this: