Setting up Microsoft Graph API with App Only Authentication in Java Server

Geethu Pachariyan 0 Reputation points
2024-09-11T10:14:41.3233333+00:00

Hi,

I am trying to create a Java project that converts a Word file to a PDF file using the Microsoft Graph API. I will create the Word file and upload it to OneDrive using the Graph API and then download it as a PDF. As this is a service, I want app-only authentication for my application.

I have created an application in the Azure AD portal and obtained the client ID, tenant ID, and client secret as per the documentation. I have given all the necessary permissions for the operation, including User.ReadBasic.All, User.Read.All, File.Read.All, File.ReadWrite.All, Sites.ReadWrite.All, and Directory.Read.All. Please let me know if I've missed any permission.

I am successfully getting the token but cannot find the proper app-only authentication flow-based code for creating a new folder in OneDrive and uploading a file to it. Also, I need an work flow for converting the file to PDF and downloading it to my local. I can only find the API for delegated AUTH application. Also, I can see the driver ID and driver item ID in the API for going to the particular driver for upload but not understanding how I get those IDs. So please help me create an app-only authentication flow-based application for converting a Word file to PDF.

Please find my poc

package graphapponlytutorial;

import java.io.IOException;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Properties;
import java.util.Scanner;

import com.azure.core.credential.AccessToken;
import com.azure.core.credential.TokenRequestContext;
import com.azure.identity.ClientSecretCredential;
import com.azure.identity.ClientSecretCredentialBuilder;
import com.microsoft.graph.models.DriveItem;
import com.microsoft.graph.models.DriveItemCollectionResponse;
import com.microsoft.graph.models.Folder;
import com.microsoft.graph.models.User;
import com.microsoft.graph.models.UserCollectionResponse;
import com.microsoft.graph.serviceclient.GraphServiceClient;

/**
 * Hello world!
 *
 */
public class App
{
    public static void main(String[] args) {
        System.out.println("Java App-Only Graph Tutorial");
        System.out.println();

        final Properties oAuthProperties = new Properties();
        try {
            oAuthProperties.load(App.class.getResourceAsStream("oAuth.properties"));
        } catch (IOException e) {
            System.out.println("Unable to read OAuth configuration. Make sure you have a properly formatted oAuth.properties file. See README for details.");
            return;
        }
        initializeGraph(oAuthProperties);
        // Display access token
        displayAccessToken();
        // Run any Graph code
        makeGraphCall();
    }
    private static void initializeGraph(Properties properties) {
        try {
            Graph.initializeGraphForAppOnlyAuth(properties);
        } catch (Exception e)
        {
            System.out.println("Error initializing Graph for user auth");
            System.out.println(e.getMessage());
        }
    }

    private static void displayAccessToken() {
        try {
            final String accessToken = Graph.getAppOnlyToken();
            System.out.println("Access token: " + accessToken);
        } catch (Exception e) {
            System.out.println("Error getting access token");
            System.out.println(e.getMessage());
        }
    }
    private static void makeGraphCall() {
        try {
            Graph.makeGraphCall();
        } catch (Exception e) {
            System.out.println("Error making Graph call");
            e.printStackTrace();
        }
    }
}

class Graph {
    private static Properties _properties;
    private static ClientSecretCredential _clientSecretCredential;
    private static GraphServiceClient _appClient;

    public static void initializeGraphForAppOnlyAuth(Properties properties) throws Exception {
        // Ensure properties isn't null
        if (properties == null) {
            throw new Exception("Properties cannot be null");
        }

        _properties = properties;

        if (_clientSecretCredential == null) {
            final String clientId = _properties.getProperty("app.clientId");
            final String tenantId = _properties.getProperty("app.tenantId");
            final String clientSecret = _properties.getProperty("app.clientSecret");

            _clientSecretCredential = new ClientSecretCredentialBuilder()
                    .clientId(clientId)
                    .tenantId(tenantId)
                    .clientSecret(clientSecret)
                    .build();
        }

        if (_appClient == null) {
            _appClient = new GraphServiceClient(_clientSecretCredential,
                    new String[] { "https://graph.microsoft.com/.default" });
        }
    }

    public static String getAppOnlyToken() throws Exception {
        // Ensure credential isn't null
        if (_clientSecretCredential == null) {
            throw new Exception("Graph has not been initialized for app-only auth");
        }

        // Request the .default scope as required by app-only auth
        final String[] graphScopes = new String[] {"https://graph.microsoft.com/.default"};

        final TokenRequestContext context = new TokenRequestContext();
        context.addScopes(graphScopes);

        final AccessToken token = _clientSecretCredential.getToken(context).block();
        return token.getToken();
    }

    public static void getDriverItems(String driver, String driverItemId) {
        DriveItemCollectionResponse collectionResponse =  _appClient.drives().byDriveId(driver).items().byDriveItemId(driverItemId).children().get();
        System.out.println(collectionResponse.getValue());
    }
    public static void makeGraphCall() {
        // Create a folder by posting a new DriveItem
        DriveItem folder = new DriveItem();
        folder.setName("NewFolder");  // Name of the folder you want to create
        folder.setFolder(new Folder()); // Indicating it's a folder
        HashMap<String, Object> additionalData = new HashMap<String, Object>();
        folder.setAdditionalData(additionalData);
        additiona
        String myDriveId = _appClient.users().byUserId(userId)
                .drive()
                .get().getId();
// Create folder in the root of the drive
        DriveItemCollectionResponse newFolder =
                _appClient
//                .users().byUserId(userId)
                        .drives().byDriveId(myDriveId)
                        .items() // Specify the folder path
                        .get();

//        _appClient
//                .users()
//                .get()
//                .getValue()
//                .forEach(user -> System.out.println("User: " + user.getId() + " - " + user.getDisplayName()));


//                .get().getRoot(); // This refers to the root directory
//                .buildRequest()
//                .post(folder);
        System.out.println("Folder created with ID: " );
    }
}


<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.azure</groupId>
      <artifactId>azure-sdk-bom</artifactId>
      <version>1.2.10</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <!-- Include the sdk as a dependency -->
    <groupId>com.microsoft.graph</groupId>
    <artifactId>microsoft-graph</artifactId>
    <!--x-release-please-start-version-->
    <version>[6.0,)</version>
    <!--x-release-please-end-->
  </dependency>
  <dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-identity</artifactId>
    <version>1.13.1</version> <!-- Or the latest version -->
  </dependency>
  <dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-core</artifactId>
    <version>1.51.0</version> <!-- Or the latest version -->
  </dependency>
</dependencies>

Thank you, Geethu P

Word
Word
A family of Microsoft word processing software products for creating web, email, and print documents.
859 questions
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
12,113 questions
OneDrive
OneDrive
A Microsoft file hosting and synchronization service.
1,128 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Yakun Huang-MSFT 5,415 Reputation points Microsoft Vendor
    2024-09-12T10:01:45.8133333+00:00

    Hi @Geethu Pachariyan

    You can refer to the following documents for creating folders in OneDrive, as well as uploading files to OneDrive, which you can convert to the format you want when downloading files.

    For a detailed call path, see the documentation, which lists the application permissions you need to grant, along with code examples like this:

    User's image

    User's image

    https://learn.microsoft.com/en-us/graph/api/driveitem-post-children?view=graph-rest-1.0&tabs=java

    https://learn.microsoft.com/en-us/graph/api/driveitem-put-content?view=graph-rest-1.0&tabs=http

    https://learn.microsoft.com/en-us/graph/api/driveitem-get-content-format?view=graph-rest-1.0&tabs=http

    Hope this helps.

    If the reply is helpful, please click Accept Answer and kindly upvote it. If you have additional questions about this answer, please click Comment.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.