I have successfully created a MS Graph Client using Azure AD and JAVA. I have used the ClientSecretCredential for authentication. I believe the access token being received is valid too. However, I now want to get access to my (outlook) mailbox, using MS Graph and JAVA, to count the total number of emails in my Inbox Folder. Please find my code and errors below. I think it's because the code is for Delegated and not Application Permissions. Kindly help.
package JAVA_MicrosoftGraphAPI;
import java.net.URL;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.apache.log4j.PropertyConfigurator;
import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.microsoft.graph.authentication.TokenCredentialAuthProvider;
import com.microsoft.graph.logger.DefaultLogger;
import com.microsoft.graph.logger.LoggerLevel;
import com.microsoft.graph.options.Option;
import com.microsoft.graph.options.QueryOption;
import com.microsoft.graph.requests.GraphServiceClient;
import com.microsoft.graph.requests.MessageCollectionPage;
public class soTest {
// for requirements visit:
// https://github.com/Azure/azure-sdk-for-java/wiki/Set-up-Your-Environment-for-Authentication#enable-applications-for-device-code-flow
private final static String CLIENT_ID = "XXXXXXXXXXXXX";
private final static String TENANT_ID = "XXXXXXXXXXXXX";
private final static String SECRET_Value = "XXXXXXXXXXXXX";
// Set the scopes for your ms-graph request
private final static List<String> SCOPES = Arrays.asList("https://graph.microsoft.com/.default");
public static void main(String[] args) throws Exception {
final ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
.clientId(CLIENT_ID)
.clientSecret(SECRET_Value)
.tenantId(TENANT_ID)
.build();
final TokenCredentialAuthProvider tokenCredAuthProvider = new TokenCredentialAuthProvider(SCOPES, clientSecretCredential);
System.out.println("First Step Reached. ");
// Create default logger to only log errors
DefaultLogger logger = new DefaultLogger();
logger.setLoggingLevel(LoggerLevel.ERROR);
// Build a Graph client
GraphServiceClient graphClient = GraphServiceClient.builder()
.authenticationProvider(tokenCredAuthProvider)
.logger(logger)
.buildClient();
System.out.println("Second Step Reached. ");
// final OkHttpClient httpClient = HttpClients.createDefault(tokenCredAuthProvider);
// final Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/me").build();
// Redirecting to web browser and signing in for authentication and connection.
URL myUrl = new URL("https://graph.microsoft.com/v1.0/me/");
final String accessToken = tokenCredAuthProvider.getAuthorizationTokenAsync(myUrl).get();
System.out.println("Access token --> " accessToken);
LinkedList<Option> requestOptions = new LinkedList<Option>();
requestOptions.add(new QueryOption("/select", "internetMessageHeaders"));
MessageCollectionPage messages = graphClient.me().messages()
.buildRequest( requestOptions )
.get();
}
}
Exception in thread "main" com.microsoft.graph.http.GraphServiceException: Error code: BadRequest
Error message: /me request is only valid with delegated authentication flow.
GET https://graph.microsoft.com/v1.0/me/messages?/select=internetMessageHeaders
SdkVersion : graph-java/v5.14.0
400 : Bad Request
[...]
[Some information was truncated for brevity, enable debug logging for more details]
at com.microsoft.graph.http.GraphServiceException.createFromResponse(GraphServiceException.java:419)
at com.microsoft.graph.http.GraphServiceException.createFromResponse(GraphServiceException.java:378)
at com.microsoft.graph.http.CoreHttpProvider.handleErrorResponse(CoreHttpProvider.java:514)
at com.microsoft.graph.http.CoreHttpProvider.processResponse(CoreHttpProvider.java:443)
at com.microsoft.graph.http.CoreHttpProvider.sendRequestInternal(CoreHttpProvider.java:409)
at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:226)
at com.microsoft.graph.http.CoreHttpProvider.send(CoreHttpProvider.java:203)
at com.microsoft.graph.http.BaseCollectionRequest.send(BaseCollectionRequest.java:103)
at com.microsoft.graph.http.BaseEntityCollectionRequest.get(BaseEntityCollectionRequest.java:78)
at JAVA_MicrosoftGraphAPI.soTest.main(soTest.java:75)
CodePudding user response:
It seems you are using Client credential flow. This implies that the token will have application claims i.e. running in the context of an application. Therefore you cannot use /me endpoint here.
You can use users/id instead. Alternatively, you can use OAuth authorization code flow (where the token will have both user as well as application claims ) to leverage /me endpoint.
Follow tutorial here to generate access token accordingly.