Skip to content

Commit ff13f24

Browse files
authored
Merge pull request #1755 from microsoftgraph/feat/auth-handler
Support Authorization Handler in Graph Client Factory
2 parents 08d812e + 7b7561a commit ff13f24

File tree

5 files changed

+161
-15
lines changed

5 files changed

+161
-15
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,23 @@ The nature of the Graph API is such that the SDK needs quite a large set of clas
5959

6060
Register your application by following the steps at [Register your app with the Microsoft Identity Platform](https://docs.microsoft.com/graph/auth-register-app-v2).
6161

62-
### 2.2 Create an IAuthenticationProvider object
62+
### 2.2 Create an AuthenticationProvider object
6363

64-
An instance of the **HttpClients** class handles building client. To create a new instance of this class, you need to provide an instance of `IAuthenticationProvider`, which can authenticate requests to Microsoft Graph.
64+
[Initialize an `AuthenticationProvider`](https://learn.microsoft.com/en-us/graph/sdks/choose-authentication-providers?view=graph-rest-1.0&tabs=java) based on your preferred authentication flow
6565

66-
For an example of how to get an authentication provider, see [choose a Microsoft Graph authentication provider](https://docs.microsoft.com/graph/sdks/choose-authentication-providers?tabs=Java).
66+
### 2.3 Get a OkHttpClient object
6767

68-
### 2.3 Get a HttpClients object
68+
You must get an **OkHttpClient** object to make requests against the service.
6969

70-
You must get a **HttpClients** object to make requests against the service.
70+
Using the `GraphClientFactory`, you can initialize an `OkHttpClient` pre-configured for use with Microsoft Graph
7171

7272
```java
73-
OkHttpClient client = HttpClients.createDefault(iAuthenticationProvider);
73+
OkHttpClient client = GraphClientFactory.create(authenticationProvider).build();
7474
```
7575

7676
## 3. Make requests against the service
7777

78-
After you have a HttpClients that is authenticated, you can begin making calls against the service. The requests against the service look like our [REST API](https://developer.microsoft.com/en-us/graph/docs/concepts/overview).
78+
After you have an OkHttpClient that is authenticated, you can begin making calls against the service. The requests against the service look like our [REST API](https://developer.microsoft.com/en-us/graph/docs/concepts/overview).
7979

8080
### 3.1 Get the user's details
8181

gradle/dependencies.gradle

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ dependencies {
1414
api 'com.squareup.okhttp3:okhttp:4.12.0'
1515
api 'com.azure:azure-core:1.52.0'
1616

17-
api 'com.microsoft.kiota:microsoft-kiota-abstractions:1.4.0'
18-
api 'com.microsoft.kiota:microsoft-kiota-authentication-azure:1.4.0'
19-
implementation 'com.microsoft.kiota:microsoft-kiota-http-okHttp:1.4.0'
20-
implementation 'com.microsoft.kiota:microsoft-kiota-serialization-json:1.4.0'
21-
implementation 'com.microsoft.kiota:microsoft-kiota-serialization-text:1.4.0'
22-
implementation 'com.microsoft.kiota:microsoft-kiota-serialization-form:1.4.0'
23-
implementation 'com.microsoft.kiota:microsoft-kiota-serialization-multipart:1.4.0'
17+
api 'com.microsoft.kiota:microsoft-kiota-abstractions:1.5.0'
18+
api 'com.microsoft.kiota:microsoft-kiota-authentication-azure:1.5.0'
19+
implementation 'com.microsoft.kiota:microsoft-kiota-http-okHttp:1.5.0'
20+
implementation 'com.microsoft.kiota:microsoft-kiota-serialization-json:1.5.0'
21+
implementation 'com.microsoft.kiota:microsoft-kiota-serialization-text:1.5.0'
22+
implementation 'com.microsoft.kiota:microsoft-kiota-serialization-form:1.5.0'
23+
implementation 'com.microsoft.kiota:microsoft-kiota-serialization-multipart:1.5.0'
2424
}

src/main/java/com/microsoft/graph/core/requests/GraphClientFactory.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import com.microsoft.graph.core.CoreConstants;
44
import com.microsoft.graph.core.requests.middleware.GraphTelemetryHandler;
55
import com.microsoft.graph.core.requests.options.GraphClientOption;
6+
import com.microsoft.kiota.authentication.BaseBearerTokenAuthenticationProvider;
67
import com.microsoft.kiota.http.KiotaClientFactory;
8+
import com.microsoft.kiota.http.middleware.AuthorizationHandler;
79
import com.microsoft.kiota.http.middleware.UrlReplaceHandler;
810
import com.microsoft.kiota.http.middleware.options.UrlReplaceHandlerOption;
911
import okhttp3.Interceptor;
@@ -37,6 +39,33 @@ public static OkHttpClient.Builder create() {
3739
public static OkHttpClient.Builder create(@Nonnull Interceptor... interceptors) {
3840
return create(new GraphClientOption(), interceptors);
3941
}
42+
43+
/**
44+
* OkHttpClient Builder for Graph with specified Interceptors
45+
* @param interceptors desired interceptors for use in requests.
46+
* @return an OkHttpClient Builder instance.
47+
*/
48+
@Nonnull
49+
public static OkHttpClient.Builder create(@Nonnull List<Interceptor> interceptors) {
50+
return create(new GraphClientOption(), interceptors.toArray(new Interceptor[0]));
51+
}
52+
53+
/**
54+
* OkHttpClient Builder for Graph with specified AuthenticationProvider.
55+
* Adds an AuthorizationHandler to the OkHttpClient Builder.
56+
* @param authenticationProvider the AuthenticationProvider to use for requests.
57+
* @return an OkHttpClient Builder instance.
58+
*/
59+
@Nonnull
60+
public static OkHttpClient.Builder create(@Nonnull BaseBearerTokenAuthenticationProvider authenticationProvider) {
61+
final GraphClientOption graphClientOption = new GraphClientOption();
62+
final Interceptor[] interceptors = createDefaultGraphInterceptors(graphClientOption);
63+
final ArrayList<Interceptor> interceptorList = new ArrayList<>(Arrays.asList(interceptors));
64+
interceptorList.add(new AuthorizationHandler(authenticationProvider));
65+
graphClientOption.featureTracker.setFeatureUsage(FeatureFlag.AUTH_HANDLER_FLAG);
66+
return create(graphClientOption, interceptorList);
67+
}
68+
4069
/**
4170
* OkHttpClient Builder for Graph with specified Interceptors and GraphClientOption.
4271
*
@@ -60,6 +89,18 @@ public static OkHttpClient.Builder create(@Nonnull GraphClientOption graphClient
6089
}
6190
return builder;
6291
}
92+
93+
/**
94+
* OkHttpClient Builder for Graph with specified Interceptors and GraphClientOption.
95+
* @param graphClientOption the GraphClientOption for use in requests.
96+
* @param interceptors desired interceptors for use in requests.
97+
* @return an OkHttpClient Builder instance.
98+
*/
99+
@Nonnull
100+
public static OkHttpClient.Builder create(@Nonnull GraphClientOption graphClientOption, @Nonnull List<Interceptor> interceptors) {
101+
return create(graphClientOption, interceptors.toArray(new Interceptor[0]));
102+
}
103+
63104
/**
64105
* The OkHttpClient Builder with optional GraphClientOption
65106
*
@@ -92,6 +133,5 @@ private static void addDefaultFeatureUsages(GraphClientOption graphClientOption)
92133
graphClientOption.featureTracker.setFeatureUsage(FeatureFlag.RETRY_HANDLER_FLAG);
93134
graphClientOption.featureTracker.setFeatureUsage(FeatureFlag.REDIRECT_HANDLER_FLAG);
94135
graphClientOption.featureTracker.setFeatureUsage(FeatureFlag.URL_REPLACEMENT_FLAG);
95-
graphClientOption.featureTracker.setFeatureUsage(FeatureFlag.BATCH_REQUEST_FLAG);
96136
}
97137
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.microsoft.graph.core.requests;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertNotNull;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
import static org.mockito.ArgumentMatchers.any;
7+
import static org.mockito.ArgumentMatchers.anyMap;
8+
import static org.mockito.Mockito.mock;
9+
import static org.mockito.Mockito.when;
10+
11+
import java.io.IOException;
12+
import java.net.URI;
13+
14+
import org.junit.jupiter.api.Test;
15+
16+
import com.microsoft.graph.core.authentication.AzureIdentityAccessTokenProvider;
17+
import com.microsoft.graph.core.authentication.AzureIdentityAuthenticationProvider;
18+
import com.microsoft.kiota.authentication.AccessTokenProvider;
19+
import com.microsoft.kiota.authentication.AllowedHostsValidator;
20+
import com.microsoft.kiota.authentication.BaseBearerTokenAuthenticationProvider;
21+
22+
import okhttp3.OkHttpClient;
23+
import okhttp3.Request;
24+
import okhttp3.Response;
25+
26+
class GraphClientFactoryTest {
27+
28+
private static final String ACCESS_TOKEN_STRING = "token";
29+
30+
@Test
31+
void testCreateWithAuthenticationProvider() throws IOException {
32+
final BaseBearerTokenAuthenticationProvider mockAuthenticationProvider =
33+
getMockAuthenticationProvider();
34+
OkHttpClient graphClient = GraphClientFactory.create(mockAuthenticationProvider).addInterceptor(new MockResponseHandler()).build();
35+
36+
Request request = new Request.Builder().url("https://graph.microsoft.com/v1.0/me").build();
37+
Response response = graphClient.newCall(request).execute();
38+
39+
assertEquals(200, response.code());
40+
assertNotNull(response.request());
41+
assertTrue(response.request().headers().names().contains("Authorization"));
42+
assertEquals("Bearer " + ACCESS_TOKEN_STRING, response.request().header("Authorization"));
43+
}
44+
45+
private static BaseBearerTokenAuthenticationProvider getMockAuthenticationProvider() {
46+
final AccessTokenProvider mockAccessTokenProvider = mock(AzureIdentityAccessTokenProvider.class);
47+
when(mockAccessTokenProvider.getAuthorizationToken(any(URI.class), anyMap()))
48+
.thenReturn(ACCESS_TOKEN_STRING);
49+
when(mockAccessTokenProvider.getAllowedHostsValidator()).thenReturn(new AllowedHostsValidator("graph.microsoft.com"));
50+
final AzureIdentityAuthenticationProvider mockAuthenticationProvider =
51+
mock(AzureIdentityAuthenticationProvider.class);
52+
when(mockAuthenticationProvider.getAccessTokenProvider())
53+
.thenReturn(mockAccessTokenProvider);
54+
return mockAuthenticationProvider;
55+
}
56+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.microsoft.graph.core.requests;
2+
3+
import java.io.IOException;
4+
5+
import okhttp3.Interceptor;
6+
import okhttp3.MediaType;
7+
import okhttp3.Protocol;
8+
import okhttp3.Response;
9+
import okhttp3.ResponseBody;
10+
import okio.Buffer;
11+
12+
class MockResponseHandler implements Interceptor {
13+
14+
private int statusCode;
15+
16+
public MockResponseHandler(int statusCode) {
17+
this.statusCode = statusCode;
18+
}
19+
20+
public MockResponseHandler() {
21+
this.statusCode = 200;
22+
}
23+
24+
@Override
25+
public Response intercept(Chain chain) throws IOException {
26+
final var request = chain.request();
27+
final var requestBody = request.body();
28+
if (request != null && requestBody != null) {
29+
final var buffer = new Buffer();
30+
requestBody.writeTo(buffer);
31+
return new Response.Builder()
32+
.code(this.statusCode)
33+
.message("OK")
34+
.protocol(Protocol.HTTP_1_1)
35+
.request(request)
36+
.body(
37+
ResponseBody.create(
38+
buffer.readByteArray(), MediaType.parse("application/json")))
39+
.build();
40+
}
41+
return new Response.Builder()
42+
.code(this.statusCode)
43+
.message("OK")
44+
.protocol(Protocol.HTTP_1_1)
45+
.request(request)
46+
.body(ResponseBody.create("", MediaType.parse("application/json")))
47+
.build();
48+
}
49+
50+
}

0 commit comments

Comments
 (0)