Skip to content

Commit f2a2747

Browse files
authored
Identity - add browser customization options (Azure#36183)
1 parent 5996565 commit f2a2747

File tree

7 files changed

+106
-2
lines changed

7 files changed

+106
-2
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.azure.identity;
5+
6+
/**
7+
* Represent Options to customize browser view.
8+
*/
9+
public class BrowserCustomizationOptions {
10+
private String htmlMessageSuccess;
11+
private String htmlMessageError;
12+
13+
/**
14+
* Configures the property to set HtmlMessageSuccess which the browser will show to the user when the user
15+
* finishes authenticating successfully.
16+
*
17+
* @param htmlMessageSuccess the message to display when user finishes authenticating.
18+
* @return the updated options.
19+
*/
20+
public BrowserCustomizationOptions setHtmlMessageSuccess(String htmlMessageSuccess) {
21+
this.htmlMessageSuccess = htmlMessageSuccess;
22+
return this;
23+
}
24+
25+
/**
26+
* Configure the property to set HtmlMessageError which the browser will show to the user when the user
27+
* finishes authenticating, but an error occurred. You can use a string format e.g.
28+
* "An error has occurred: {0} details: {1}.", the details will be populated by the library.
29+
*
30+
* @param htmlMessageError the message to display when user finishes authenticating, but an error occurred.
31+
* @return the updated options.
32+
*/
33+
public BrowserCustomizationOptions setHtmlMessageError(String htmlMessageError) {
34+
this.htmlMessageError = htmlMessageError;
35+
return this;
36+
}
37+
38+
/**
39+
* Get the configured message which the browser will show to the user when the user
40+
* finishes authenticating successfully.
41+
*
42+
* @return the string message.
43+
*/
44+
public String getHtmlMessageSuccess() {
45+
return this.htmlMessageSuccess;
46+
}
47+
48+
/**
49+
* Get the configured message which the browser will show to the user when the user
50+
* finishes authenticating, but an error occurred.
51+
*
52+
* @return the string message.
53+
*/
54+
public String getHtmlMessageError() {
55+
return this.htmlMessageError;
56+
}
57+
}

sdk/identity/azure-identity/src/main/java/com/azure/identity/InteractiveBrowserCredentialBuilder.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,16 @@ public InteractiveBrowserCredentialBuilder additionallyAllowedTenants(List<Strin
197197
return this;
198198
}
199199

200+
/**
201+
* Configures the options for customizing the browser for interactive authentication.
202+
* @param browserCustomizationOptions the browser customization options
203+
* @return An updated instance of this builder with the browser customization options configured.
204+
*/
205+
public InteractiveBrowserCredentialBuilder browserCustomizationOptions(BrowserCustomizationOptions browserCustomizationOptions) {
206+
this.identityClientOptions.setBrowserCustomizationOptions(browserCustomizationOptions);
207+
return this;
208+
}
209+
200210
/**
201211
* Creates a new {@link InteractiveBrowserCredential} with the current configurations.
202212
*

sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentityClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,8 @@ public Mono<MsalToken> authenticateWithBrowserInteraction(TokenRequestContext re
797797
} catch (URISyntaxException e) {
798798
return Mono.error(LOGGER.logExceptionAsError(new RuntimeException(e)));
799799
}
800-
InteractiveRequestParameters.InteractiveRequestParametersBuilder builder = buildInteractiveRequestParameters(request, loginHint, redirectUri);
800+
InteractiveRequestParameters.InteractiveRequestParametersBuilder builder =
801+
buildInteractiveRequestParameters(request, loginHint, redirectUri);
801802

802803
SynchronizedAccessor<PublicClientApplication> publicClient = getPublicClientInstance(request);
803804

sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentityClientBase.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.azure.core.util.serializer.JacksonAdapter;
2828
import com.azure.core.util.serializer.SerializerAdapter;
2929
import com.azure.core.util.serializer.SerializerEncoding;
30+
import com.azure.identity.BrowserCustomizationOptions;
3031
import com.azure.identity.CredentialUnavailableException;
3132
import com.azure.identity.DeviceCodeInfo;
3233
import com.azure.identity.TokenCachePersistenceOptions;
@@ -43,6 +44,7 @@
4344
import com.microsoft.aad.msal4j.OnBehalfOfParameters;
4445
import com.microsoft.aad.msal4j.Prompt;
4546
import com.microsoft.aad.msal4j.PublicClientApplication;
47+
import com.microsoft.aad.msal4j.SystemBrowserOptions;
4648
import com.microsoft.aad.msal4j.TokenProviderResult;
4749
import com.microsoft.aad.msal4j.UserNamePasswordParameters;
4850
import reactor.core.publisher.Mono;
@@ -479,6 +481,20 @@ InteractiveRequestParameters.InteractiveRequestParametersBuilder buildInteractiv
479481
builder.claims(customClaimRequest);
480482
}
481483

484+
BrowserCustomizationOptions browserCustomizationOptions = options.getBrowserCustomizationOptions();
485+
486+
if (IdentityUtil.browserCustomizationOptionsPresent(browserCustomizationOptions)) {
487+
SystemBrowserOptions.SystemBrowserOptionsBuilder browserOptionsBuilder = SystemBrowserOptions.builder();
488+
if (!CoreUtils.isNullOrEmpty(browserCustomizationOptions.getHtmlMessageSuccess())) {
489+
browserOptionsBuilder.htmlMessageSuccess(browserCustomizationOptions.getHtmlMessageSuccess());
490+
}
491+
492+
if (!CoreUtils.isNullOrEmpty(browserCustomizationOptions.getHtmlMessageError())) {
493+
browserOptionsBuilder.htmlMessageError(browserCustomizationOptions.getHtmlMessageError());
494+
}
495+
builder.systemBrowserOptions(browserOptionsBuilder.build());
496+
}
497+
482498
if (loginHint != null) {
483499
builder.loginHint(loginHint);
484500
}

sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentityClientOptions.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.azure.core.util.logging.ClientLogger;
1616
import com.azure.identity.AzureAuthorityHosts;
1717
import com.azure.identity.AuthenticationRecord;
18+
import com.azure.identity.BrowserCustomizationOptions;
1819
import com.azure.identity.ChainedTokenCredential;
1920
import com.azure.identity.TokenCachePersistenceOptions;
2021
import com.azure.identity.implementation.util.IdentityConstants;
@@ -40,6 +41,7 @@ public final class IdentityClientOptions implements Cloneable {
4041
public static final String AZURE_POD_IDENTITY_AUTHORITY_HOST = "AZURE_POD_IDENTITY_AUTHORITY_HOST";
4142

4243
private String authorityHost;
44+
private BrowserCustomizationOptions browserCustomizationOptions;
4345
private String imdsAuthorityHost;
4446
private int maxRetry;
4547
private Function<Duration, Duration> retryTimeout;
@@ -82,6 +84,7 @@ public IdentityClientOptions() {
8284
Configuration configuration = Configuration.getGlobalConfiguration().clone();
8385
loadFromConfiguration(configuration);
8486
identityLogOptionsImpl = new IdentityLogOptionsImpl();
87+
browserCustomizationOptions = new BrowserCustomizationOptions();
8588
maxRetry = MAX_RETRY_DEFAULT_LIMIT;
8689
retryTimeout = i -> Duration.ofSeconds((long) Math.pow(2, i.getSeconds() - 1));
8790
perCallPolicies = new ArrayList<>();
@@ -659,6 +662,15 @@ public IdentityClientOptions disableInstanceDiscovery() {
659662
return this;
660663
}
661664

665+
public IdentityClientOptions setBrowserCustomizationOptions(BrowserCustomizationOptions browserCustomizationOptions) {
666+
this.browserCustomizationOptions = browserCustomizationOptions;
667+
return this;
668+
}
669+
670+
public BrowserCustomizationOptions getBrowserCustomizationOptions() {
671+
return this.browserCustomizationOptions;
672+
}
673+
662674
/**
663675
* Gets the instance discovery policy.
664676
* @return boolean indicating if instance discovery is enabled.
@@ -759,6 +771,7 @@ public IdentityClientOptions clone() {
759771
.setRetryPolicy(this.retryPolicy)
760772
.setPerCallPolicies(this.perCallPolicies)
761773
.setPerRetryPolicies(this.perRetryPolicies)
774+
.setBrowserCustomizationOptions(this.browserCustomizationOptions)
762775
.setChained(this.isChained);
763776
if (!isInstanceDiscoveryEnabled()) {
764777
clone.disableInstanceDiscovery();

sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/IdentitySyncClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,8 @@ public MsalToken authenticateWithBrowserInteraction(TokenRequestContext request,
327327
throw LOGGER.logExceptionAsError(new RuntimeException(e));
328328
}
329329

330-
InteractiveRequestParameters.InteractiveRequestParametersBuilder builder = buildInteractiveRequestParameters(request, loginHint, redirectUri);
330+
InteractiveRequestParameters.InteractiveRequestParametersBuilder builder =
331+
buildInteractiveRequestParameters(request, loginHint, redirectUri);
331332
PublicClientApplication pc = getPublicClientInstance(request).getValue();
332333
try {
333334
return new MsalToken(pc.acquireToken(builder.build()).get());

sdk/identity/azure-identity/src/main/java/com/azure/identity/implementation/util/IdentityUtil.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.azure.core.util.Configuration;
99
import com.azure.core.util.CoreUtils;
1010
import com.azure.core.util.logging.ClientLogger;
11+
import com.azure.identity.BrowserCustomizationOptions;
1112
import com.azure.identity.implementation.IdentityClientOptions;
1213

1314
import java.util.Arrays;
@@ -83,4 +84,9 @@ public static List<String> getAdditionalTenantsFromEnvironment(Configuration con
8384
return Collections.emptyList();
8485
}
8586
}
87+
88+
public static boolean browserCustomizationOptionsPresent(BrowserCustomizationOptions browserCustomizationOptions) {
89+
return !CoreUtils.isNullOrEmpty(browserCustomizationOptions.getHtmlMessageError())
90+
|| !CoreUtils.isNullOrEmpty(browserCustomizationOptions.getHtmlMessageSuccess());
91+
}
8692
}

0 commit comments

Comments
 (0)