Hot questions for Using Azure in microsoft graph

Top Java Programmings / Azure / microsoft graph

Question:

I am trying to access Microsoft Graph API using the following code in Java :-

    String url_str = "https://graph.microsoft.com/v1.0/users/";
    String access_token = getAccessToken();
    url = new URL(url_str);
    con = ( HttpURLConnection )url.openConnection();
    con.setDoInput(true);
    con.setDoOutput(true);
    con.setUseCaches(false);
    con.setRequestMethod("GET");
    con.setRequestProperty("Authorization", access_token);
    con.setRequestProperty("Accept","application/json");
    con.connect();

    br = new BufferedReader(new InputStreamReader( con.getInputStream() ));
    String str = null;
    String line;
    while((line = br.readLine()) != null) {
        str += line;
    }
    System.out.println(str);
} catch (Exception e) {
    e.printStackTrace();
}

Currently I am getting JSON String which i will need to parse further. All I want to know is there any other way which will reduce the pain of deserialization or something more better.


Answer:

Update on Martin answer, Java SDK is released and available for public preview :- https://github.com/microsoftgraph/msgraph-sdk-java.

Question:

I am trying to get a list of tasks in a ms planner. I have some code that worked with a redirect, which presented a authentication code to validate the user via the ms java api PublicClientApplication object.

'''

///
///   Already defined after registering an application in azure AD
///    private static String applicationId;
///    private static String tennantId;
///
public String getUserAccessToken(String[] scopes)  {
    try {

        PublicClientApplication app;
        try {
            // Build the MSAL application object with
            // app ID and authority

            String authority = "https://login.microsoftonline.com/";
            app = PublicClientApplication.builder(applicationId)
                    .authority(authority + tennantId + "/")
                    .build();
        } catch (MalformedURLException e) {
            return null;
        }

        // Create consumer to receive the DeviceCode object
        // This method gets executed during the flow and provides
        // the URL the user logs into and the device code to enter
        Consumer<DeviceCode> deviceCodeConsumer = (DeviceCode deviceCode) -> {
            span.log(ImmutableMap.of("event", "o365-initialise-authentication-device-code-check", "", ""));
            // Print the login information to the console
            System.out.println(deviceCode.message());
        };

        // Request a token, passing the requested permission scopes
        IAuthenticationResult result = app.acquireToken(
                DeviceCodeFlowParameters
                        .builder(scopeSet, deviceCodeConsumer)
                        .build()
        ).exceptionally(ex -> {
            return null;
        }).join();

        if (result != null) {
            return result.accessToken();
        }
    return null;
}

public void getPlan(string planId)
{

            // Build a Graph client
            graphClient = GraphServiceClient.builder()
                    .authenticationProvider((IAuthenticationProvider) authProvider)
                    .logger(logger)
                    .buildClient();

    PlannerBucketCollectionPage existingBuckets = graphClient.planner().plans(planId).buckets().buildRequest().get();
}

'''

This works with existingBuckets call returning the buckets in the plan defined by planId

I now wish to automate the code via a daemon that doesn't require user access and the authentication code is now: ''' public String getUserAccessToken(String[] scopes) {

    try {

        // Create default logger to only log errors
        DefaultLogger logger = new DefaultLogger();
        logger.setLoggingLevel(LoggerLevel.DEBUG);

        ConfidentialClientApplication app = ConfidentialClientApplication.builder(
                applicationId,
                ClientCredentialFactory.create(key))
                .authority(authority + tennantId + "/")
                .build();

        ClientCredentialParameters clientCredentialParam = ClientCredentialParameters.builder(
                Collections.singleton(GRAPH_DEFAULT_SCOPE))
                .build();

        CompletableFuture<IAuthenticationResult> future = app.acquireToken(clientCredentialParam);

        BiConsumer<IAuthenticationResult, Throwable> processAuthResult = (res, ex) -> {
            if (ex != null) {
                System.out.println("Oops! We have an exception - " + ex.getMessage());
            }
            else
            {
                System.out.println("Returned ok - " + res);
                System.out.println("Access Token - " + res.accessToken());
                System.out.println("ID Token - " + res.idToken());
            }
        };

        future.whenCompleteAsync(processAuthResult);
        future.join();

        CompletableFuture<Set<IAccount>> accountsRequest = app.getAccounts();
        BiConsumer<Set<IAccount>, Throwable> processAccountsResult = (res, ex) -> {
            if (ex != null) {
                System.out.println("Oops! We have an exception - " + ex.getMessage());
            }

            if ( res == null )
            {
                System.out.println("No accounts");
            }
            else
            {
                log.info("Found "+ res.size() + " accounts");
            }
        };

        accountsRequest.whenCompleteAsync(processAccountsResult);

        CompletableFuture<IAuthenticationResult> future1;
        try {
            future1 = app.acquireTokenSilently
                    (SilentParameters.builder(Collections.singleton(GRAPH_DEFAULT_SCOPE),
                            null)
                            .forceRefresh(true)
                            .build());
        } catch (MalformedURLException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }

        future1.join();
        IAccount account = app.getAccounts().join().iterator().next();
        app.removeAccount(account).join();

        return future.get().accessToken();
    }
    catch ( Exception ex)
    {
        log.error("Unable to get O365 token", ex);
    }
    return null;
}

'''

However, the account objects are null, and if I skip the future1 call, then I get an http error 401.

Any help / guidance gratefully received.

Thanks in advance


Answer:

Access to planner by using client credentials(without user access) is currently not supported.

You can vote it up on Microsoft Forums(Microsoft graph feature requests).

Question:

I want to Implement Microsoft Graph API for sending an email.

For that, I have referred the code from https://github.com/microsoftgraph/console-java-connect-sample.

But, The code present here is in Gradle format. I need it in Maven format.

What I Want to do is :

  1. Get The access token from GraphAPI
  2. Using This Access token Call the Send Mail API of GraphAPI

I have perfrom above two functionality using postman.

same I want to implement using Java & Maven

Please let me know if any sample available for this functionality using Maven


Answer:

Maven and Gradle are just build tools. You can use that sample, just need to create a pom.xml file with dependencies used in build.gradle file. I have done that for you.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>test2</groupId>
    <artifactId>test2</artifactId>
    <version>1.0-SNAPSHOT</version>

<dependencies>
    <dependency>
        <groupId>com.nimbusds</groupId>
        <artifactId>oauth2-oidc-sdk</artifactId>
        <version>4.5</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
        <version>20090211</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.5</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.github.scribejava</groupId>
        <artifactId>scribejava-apis</artifactId>
        <version>6.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-io</artifactId>
        <version>1.3.2</version>
    </dependency>
    <dependency>
        <groupId>com.gilecode.yagson</groupId>
        <artifactId>j9-reflection-utils</artifactId>
        <version>1.0</version>
    </dependency>
    <dependency>
        <groupId>com.microsoft.graph</groupId>
        <artifactId>microsoft-graph</artifactId>
        <version>1.5.0</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
    <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
    </build>
</project>

Download that sample and delete all the files except src folder, put the pom.xml together with src folder. A maven project has done.