Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,18 @@ public class AuthenticationRecord {
@JsonProperty("username")
private String username;

@JsonProperty("clientId")
private String clientId;


AuthenticationRecord() { }

AuthenticationRecord(IAuthenticationResult authenticationResult, String tenantId) {
AuthenticationRecord(IAuthenticationResult authenticationResult, String tenantId, String clientId) {
authority = authenticationResult.account().environment();
homeAccountId = authenticationResult.account().homeAccountId();
username = authenticationResult.account().username();
this.tenantId = tenantId;
this.clientId = clientId;
}

/**
Expand Down Expand Up @@ -67,6 +71,15 @@ public String getTenantId() {
return tenantId;
}

/**
* Get the client id of the application used for authentication.
*
* @return the client id.
*/
public String getClientId() {
return clientId;
}

/**
* Get the user principal name of the account.
*
Expand All @@ -82,14 +95,14 @@ public String getUsername() {
* @param outputStream The {@link OutputStream} to which the serialized record will be written to.
* @return A {@link Mono} containing {@link Void}
*/
public Mono<Void> serialize(OutputStream outputStream) {
public Mono<OutputStream> serialize(OutputStream outputStream) {
return Mono.defer(() -> {
try {
OBJECT_MAPPER.writeValue(outputStream, this);
} catch (IOException e) {
return Mono.error(e);
}
return Mono.empty();
return Mono.just(outputStream);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public Mono<AccessToken> getToken(TokenRequestContext request) {
.map(msalToken -> {
cachedToken.set(new MsalAuthenticationAccount(
new AuthenticationRecord(msalToken.getAuthenticationResult(),
identityClient.getTenantId())));
identityClient.getTenantId(), identityClient.getClientId())));
return (AccessToken) msalToken;
})
.doOnNext(token -> LoggingUtil.logTokenSuccess(logger, request))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,42 +48,18 @@ public AuthorizationCodeCredentialBuilder redirectUrl(String redirectUrl) {
return this;
}

/**
* Sets whether to use an unprotected file specified by <code>cacheFileLocation()</code> instead of
* Gnome keyring on Linux. This is false by default.
*
* @param allowUnencryptedCache whether to use an unprotected file for cache storage.
*
* @return An updated instance of this builder with the unprotected token cache setting set as specified.
*/
public AuthorizationCodeCredentialBuilder allowUnencryptedCache(boolean allowUnencryptedCache) {
this.identityClientOptions.allowUnencryptedCache(allowUnencryptedCache);
return this;
}

/**
* Sets the client secret for the authentication. This is required for AAD web apps. Do not set this for AAD native
* apps.
*
* @param clientSecret the secret value of the AAD application.
* @return the AuthorizationCodeCredentialBuilder itself
* @return An updated instance of this builder.
*/
public AuthorizationCodeCredentialBuilder clientSecret(String clientSecret) {
this.clientSecret = clientSecret;
return this;
}

/**
* Sets whether to enable using the shared token cache. This is disabled by default.
*
* @param enabled whether to enabled using the shared token cache.
*
* @return An updated instance of this builder with if the shared token cache enabled specified.
*/
public AuthorizationCodeCredentialBuilder enablePersistentCache(boolean enabled) {
this.identityClientOptions.enablePersistentCache(enabled);
return this;
}

/**
* Creates a new {@link AuthorizationCodeCredential} with the current configurations.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,40 @@
/**
* Defines fields exposing the well known authority hosts for the Azure Public Cloud and sovereign clouds.
*/
public final class KnownAuthorityHosts {
public final class AzureAuthorityHosts {

private KnownAuthorityHosts() { }
private AzureAuthorityHosts() { }

/**
* The host of the Azure Active Directory authority for tenants in the Azure Public Cloud.
*/
public static final String AZURE_CLOUD = "https://login.microsoftonline.com/";
public static final String AZURE_PUBLIC_CLOUD = "https://login.microsoftonline.com/";

/**
* The host of the Azure Active Directory authority for tenants in the Azure China Cloud.
*/
public static final String AZURE_CHINA_CLOUD = "https://login.chinacloudapi.cn/";
public static final String AZURE_CHINA = "https://login.chinacloudapi.cn/";

/**
* The host of the Azure Active Directory authority for tenants in the Azure German Cloud.
*/
public static final String AZURE_GERMAN_CLOUD = "https://login.microsoftonline.de/";
public static final String AZURE_GERMANY = "https://login.microsoftonline.de/";

/**
* The host of the Azure Active Directory authority for tenants in the Azure US Government Cloud.
*/
public static final String AZURE_US_GOVERNMENT = "https://login.microsoftonline.us/";
public static final String AZURE_GOVERNMENT = "https://login.microsoftonline.us/";


static String getDefaultScope(String authorityHost) {
switch (authorityHost) {
case AZURE_CLOUD:
case AZURE_PUBLIC_CLOUD:
return "https://management.core.windows.net//.default";
case AZURE_CHINA_CLOUD:
case AZURE_CHINA:
return "https://management.core.chinacloudapi.cn//.default";
case AZURE_GERMAN_CLOUD:
case AZURE_GERMANY:
return "https://management.core.cloudapi.de//.default";
case AZURE_US_GOVERNMENT:
case AZURE_GOVERNMENT:
return "https://management.core.usgovcloudapi.net//.default";
default:
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,4 @@ public Mono<AccessToken> getToken(TokenRequestContext request) {
return Mono.error(last);
}));
}


/**
* Get the read-only list of credentials sequentially used to attempt authentication.
*
* @return The list of {@link TokenCredential}.
*/
public List<TokenCredential> getCredentials() {
return credentials;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,25 @@ public ClientCertificateCredentialBuilder pfxCertificate(String certificatePath,
}

/**
* Sets whether to enable using the shared token cache. This is disabled by default.
* Allows to use an unprotected file specified by <code>cacheFileLocation()</code> instead of
* Gnome keyring on Linux. This is restricted by default.
*
* @param enabled indicates whether to enable using the shared token cache.
* @return An updated instance of this builder.
*/
public ClientCertificateCredentialBuilder allowUnencryptedCache() {
this.identityClientOptions.allowUnencryptedCache();
return this;
}

/**
* Enables the shared token cache which is disabled by default. If enabled, the credential will store tokens
* in a cache persisted to the machine, protected to the current user, which can be shared by other credentials
* and processes.
*
* @return An updated instance of this builder.
*/
public ClientCertificateCredentialBuilder enablePersistentCache(boolean enabled) {
this.identityClientOptions.enablePersistentCache(enabled);
public ClientCertificateCredentialBuilder enablePersistentCache() {
this.identityClientOptions.enablePersistentCache();
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,25 @@ public ClientSecretCredentialBuilder clientSecret(String clientSecret) {
}

/**
* Sets whether to enable using the shared token cache. This is disabled by default.
* Enables the shared token cache which is disabled by default. If enabled, the credential will store tokens
* in a cache persisted to the machine, protected to the current user, which can be shared by other credentials
* and processes.
*
* @param enabled indicates whether to enable using the shared token cache.
* @return An updated instance of this builder.
*/
public ClientSecretCredentialBuilder enablePersistentCache() {
this.identityClientOptions.enablePersistentCache();
return this;
}

/**
* Allows to use an unprotected file specified by <code>cacheFileLocation()</code> instead of
* Gnome keyring on Linux. This is restricted by default.
*
* @return An updated instance of this builder.
*/
public ClientSecretCredentialBuilder enablePersistentCache(boolean enabled) {
this.identityClientOptions.enablePersistentCache(enabled);
public ClientSecretCredentialBuilder allowUnencryptedCache() {
this.identityClientOptions.allowUnencryptedCache();
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,4 @@ public final class DefaultAzureCredential extends ChainedTokenCredential {
DefaultAzureCredential(List<TokenCredential> tokenCredentials) {
super(tokenCredentials);
}


/**
* {@inheritDoc}
* The credentials in the returned list and their order may change in future versions of Identity.
* This API is not intended to be used in production ready code and should only be used for development purposes.
*
* @return The list of {@link TokenCredential}.
*/
public List<TokenCredential> getCredentials() {
return super.getCredentials();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public Mono<AccessToken> getToken(TokenRequestContext request) {
*
* @return The {@link AuthenticationRecord} which can be used to silently authenticate the account
* on future execution if persistent caching was enabled via
* {@link DeviceCodeCredentialBuilder#enablePersistentCache(boolean)} when credential was instantiated.
* {@link DeviceCodeCredentialBuilder#enablePersistentCache()} when credential was instantiated.
*/
public Mono<AuthenticationRecord> authenticate(TokenRequestContext request) {
return Mono.defer(() -> identityClient.authenticateWithDeviceCode(request, challengeConsumer))
Expand All @@ -108,10 +108,10 @@ public Mono<AuthenticationRecord> authenticate(TokenRequestContext request) {
*
* @return The {@link AuthenticationRecord} which can be used to silently authenticate the account
* on future execution if persistent caching was enabled via
* {@link DeviceCodeCredentialBuilder#enablePersistentCache(boolean)} when credential was instantiated.
* {@link DeviceCodeCredentialBuilder#enablePersistentCache()} when credential was instantiated.
*/
public Mono<AuthenticationRecord> authenticate() {
String defaultScope = KnownAuthorityHosts.getDefaultScope(authorityHost);
String defaultScope = AzureAuthorityHosts.getDefaultScope(authorityHost);
if (defaultScope == null) {
return Mono.error(logger.logExceptionAsError(new CredentialUnavailableException("Authenticating in this "
+ "environment requires specifying a TokenRequestContext.")));
Expand All @@ -123,7 +123,7 @@ private AccessToken updateCache(MsalToken msalToken) {
cachedToken.set(
new MsalAuthenticationAccount(
new AuthenticationRecord(msalToken.getAuthenticationResult(),
identityClient.getTenantId())));
identityClient.getTenantId(), identityClient.getClientId())));
return msalToken;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,25 @@ public DeviceCodeCredentialBuilder challengeConsumer(
}

/**
* Sets whether to use an unprotected file specified by <code>cacheFileLocation()</code> instead of
* Gnome keyring on Linux. This is false by default.
* Allows to use an unprotected file specified by <code>cacheFileLocation()</code> instead of
* Gnome keyring on Linux. This is restricted by default.
*
* @param allowUnencryptedCache whether to use an unprotected file for cache storage.
*
* @return An updated instance of this builder with the unprotected token cache setting set as specified.
* @return An updated instance of this builder.
*/
public DeviceCodeCredentialBuilder allowUnencryptedCache(boolean allowUnencryptedCache) {
this.identityClientOptions.allowUnencryptedCache(allowUnencryptedCache);
public DeviceCodeCredentialBuilder allowUnencryptedCache() {
this.identityClientOptions.allowUnencryptedCache();
return this;
}

/**
* Sets whether to enable using the shared token cache. This is disabled by default.
*
* @param enabled whether to enabled using the shared token cache.
* Enables the shared token cache which is disabled by default. If enabled, the credential will store tokens
* in a cache persisted to the machine, protected to the current user, which can be shared by other credentials
* and processes.
*
* @return An updated instance of this builder with if the shared token cache enabled specified.
*/
public DeviceCodeCredentialBuilder enablePersistentCache(boolean enabled) {
this.identityClientOptions.enablePersistentCache(enabled);
public DeviceCodeCredentialBuilder enablePersistentCache() {
this.identityClientOptions.enablePersistentCache();
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,17 @@ public class InteractiveBrowserCredential implements TokenCredential {
* {@code http://localhost:{port}} must be registered as a valid reply URL on the application.
*
* @param clientId the client ID of the application
* @param clientSecret the client secret of the application
* @param tenantId the tenant ID of the application
* @param port the port on which the credential will listen for the browser authentication result
* @param automaticAuthentication indicates whether automatic authentication should be attempted or not.
* @param identityClientOptions the options for configuring the identity client
*/
InteractiveBrowserCredential(String clientId, String tenantId, int port, boolean automaticAuthentication,
String clientSecret, IdentityClientOptions identityClientOptions) {
IdentityClientOptions identityClientOptions) {
this.port = port;
identityClient = new IdentityClientBuilder()
.tenantId(tenantId)
.clientId(clientId)
.clientSecret(clientSecret)
.identityClientOptions(identityClientOptions)
.build();
cachedToken = new AtomicReference<>();
Expand Down Expand Up @@ -93,7 +91,7 @@ public Mono<AccessToken> getToken(TokenRequestContext request) {
*
* @return The {@link AuthenticationRecord} which can be used to silently authenticate the account
* on future execution if persistent caching was enabled via
* {@link InteractiveBrowserCredentialBuilder#enablePersistentCache(boolean)} when credential was instantiated.
* {@link InteractiveBrowserCredentialBuilder#enablePersistentCache()} when credential was instantiated.
*/
public Mono<AuthenticationRecord> authenticate(TokenRequestContext request) {
return Mono.defer(() -> identityClient.authenticateWithBrowserInteraction(request, port))
Expand All @@ -106,10 +104,10 @@ public Mono<AuthenticationRecord> authenticate(TokenRequestContext request) {
*
* @return The {@link AuthenticationRecord} which can be used to silently authenticate the account
* on future execution if persistent caching was enabled via
* {@link InteractiveBrowserCredentialBuilder#enablePersistentCache(boolean)} when credential was instantiated.
* {@link InteractiveBrowserCredentialBuilder#enablePersistentCache()} when credential was instantiated.
*/
public Mono<AuthenticationRecord> authenticate() {
String defaultScope = KnownAuthorityHosts.getDefaultScope(authorityHost);
String defaultScope = AzureAuthorityHosts.getDefaultScope(authorityHost);
if (defaultScope == null) {
return Mono.error(logger.logExceptionAsError(new CredentialUnavailableException("Authenticating in this "
+ "environment requires specifying a TokenRequestContext.")));
Expand All @@ -121,7 +119,7 @@ private AccessToken updateCache(MsalToken msalToken) {
cachedToken.set(
new MsalAuthenticationAccount(
new AuthenticationRecord(msalToken.getAuthenticationResult(),
identityClient.getTenantId())));
identityClient.getTenantId(), identityClient.getClientId())));
return msalToken;
}

Expand Down
Loading