Skip to content

Commit

Permalink
Add getBearerTokenSupplier (Azure#42152)
Browse files Browse the repository at this point in the history
* Add getBearerTokenSupplier

This supports our Open AI work.

Fixes Azure#41611

* PR feedback

* linter fixes

* pr feedback

* fix ordering of modifiers
  • Loading branch information
billwert authored Oct 1, 2024
1 parent 104f3da commit a4436a8
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
1 change: 1 addition & 0 deletions sdk/identity/azure-identity/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<!-- Configures the Java 9+ run to perform the required module exports, opens, and reads that are necessary for testing but shouldn't be part of the module-info. -->
<javaModulesSurefireArgLine>
--add-opens java.xml/jdk.xml.internal=ALL-UNNAMED
--add-exports com.azure.core/com.azure.core.implementation.util=ALL-UNNAMED
</javaModulesSurefireArgLine>

<spotbugs.includeTests>true</spotbugs.includeTests>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.identity;

import com.azure.core.credential.TokenCredential;
import com.azure.core.http.HttpHeaderName;
import com.azure.core.http.HttpMethod;
import com.azure.core.http.HttpPipeline;
import com.azure.core.http.HttpPipelineBuilder;
import com.azure.core.http.HttpRequest;
import com.azure.core.http.HttpResponse;
import com.azure.core.http.policy.BearerTokenAuthenticationPolicy;
import com.azure.core.util.Context;

import java.util.function.Supplier;

/**
* Utility methods for working with authentication.
*/
public final class AuthenticationUtil {

private AuthenticationUtil() {
}

/**
* Creates a {@link Supplier} that provides a Bearer token from the specified credential.
* The token is cached and will refresh when it expires.
* <p><strong>Using the supplier:</strong></p>
* <!-- src_embed com.azure.identity.util.getBearerTokenSupplier -->
* <pre>
* DefaultAzureCredential credential = new DefaultAzureCredentialBuilder&#40;&#41;.build&#40;&#41;;
* String scope = &quot;https:&#47;&#47;cognitiveservices.azure.com&#47;.default&quot;;
* Supplier&lt;String&gt; supplier = AuthenticationUtil.getBearerTokenSupplier&#40;credential, scope&#41;;
*
* &#47;&#47; This example simply uses the Azure SDK HTTP library to demonstrate setting the header.
* &#47;&#47; Use the token as is appropriate for your circumstances.
* HttpRequest request = new HttpRequest&#40;HttpMethod.GET, &quot;https:&#47;&#47;www.example.com&quot;&#41;;
* request.setHeader&#40;HttpHeaderName.AUTHORIZATION, &quot;Bearer &quot; + supplier.get&#40;&#41;&#41;;
* HttpClient client = HttpClient.createDefault&#40;&#41;;
* client.sendSync&#40;request, Context.NONE&#41;;
* </pre>
* <!-- end com.azure.identity.util.getBearerTokenSupplier -->
*
* @param credential The {@link TokenCredential} from which to retrieve a token.
* @param scopes The scopes as appropriate for the token you are retrieving.
* @return A {@link Supplier} which returns the bearer token as a {@link String}.
*/
public static Supplier<String> getBearerTokenSupplier(TokenCredential credential, String... scopes) {
HttpPipeline pipeline = new HttpPipelineBuilder().policies(new BearerTokenAuthenticationPolicy(credential, scopes)).build();
return () -> {
// This request will never need to go anywhere; it is simply to cause the policy to interact with
// the user's credential
HttpRequest req = new HttpRequest(HttpMethod.GET, "https://www.example.com");
try (HttpResponse res = pipeline.sendSync(req, Context.NONE)) {
return res.getRequest().getHeaders().get(HttpHeaderName.AUTHORIZATION).getValue().split(" ")[1];
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@
import com.azure.core.credential.AccessToken;
import com.azure.core.credential.TokenCredential;
import com.azure.core.credential.TokenRequestContext;
import com.azure.core.http.HttpClient;
import com.azure.core.http.HttpHeaderName;
import com.azure.core.http.HttpMethod;
import com.azure.core.http.HttpRequest;
import com.azure.core.http.ProxyOptions;
import com.azure.core.http.ProxyOptions.Type;
import com.azure.core.util.Context;
import com.azure.identity.AuthenticationRecord;
import com.azure.identity.AuthenticationUtil;
import com.azure.identity.AuthorizationCodeCredential;
import com.azure.identity.AuthorizationCodeCredentialBuilder;
import com.azure.identity.AzureCliCredential;
Expand Down Expand Up @@ -54,6 +60,7 @@
import java.io.FileOutputStream;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.util.function.Supplier;

/**
* This class contains code samples for generating javadocs through doclets for azure-identity.
Expand Down Expand Up @@ -349,4 +356,20 @@ public void silentAuthenticationSnippets() {

// END: com.azure.identity.silentauthentication
}

public void bearerTokenProviderSampleSync() {
// BEGIN: com.azure.identity.util.getBearerTokenSupplier
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build();
String scope = "https://cognitiveservices.azure.com/.default";
Supplier<String> supplier = AuthenticationUtil.getBearerTokenSupplier(credential, scope);

// This example simply uses the Azure SDK HTTP library to demonstrate setting the header.
// Use the token as is appropriate for your circumstances.
HttpRequest request = new HttpRequest(HttpMethod.GET, "https://www.example.com");
request.setHeader(HttpHeaderName.AUTHORIZATION, "Bearer " + supplier.get());
HttpClient client = HttpClient.createDefault();
client.sendSync(request, Context.NONE);
// END: com.azure.identity.util.getBearerTokenSupplier
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.identity;

import com.azure.core.test.utils.MockTokenCredential;
import org.junit.jupiter.api.Test;

import java.util.function.Supplier;

import static com.azure.identity.AuthenticationUtil.getBearerTokenSupplier;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class AuthenticationUtilTest {

@Test
public void testGetBearerTokenSupplier() {
MockTokenCredential credential = new MockTokenCredential();
Supplier<String> supplier = getBearerTokenSupplier(credential, "scope");
assertEquals("mockToken", supplier.get());
}
}

0 comments on commit a4436a8

Please sign in to comment.