Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identity API updates July 2020 #13154

Merged
merged 12 commits into from
Jul 22, 2020
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