Skip to content

Commit

Permalink
[Identity] Changes after the architects review (#18072)
Browse files Browse the repository at this point in the history
* ApplicationCredential to AzureApplicationCredential

* Removed the persistence options from DefaultAzureCredential and EnvironmentCredential

* Merged the configuration and the options bag on the OnBehalfOfCredential
  • Loading branch information
sadasant authored Oct 8, 2021
1 parent 3e3c702 commit 5a8cb4c
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 122 deletions.
6 changes: 6 additions & 0 deletions sdk/identity/identity/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ Azure Service Fabric support hasn't been added on the initial version 2 of Ident
- Removed the `allowMultiTenantAuthentication` option from all of the credentials. Multi-tenant authentication is now enabled by default. On Node.js, it can be disabled with the `AZURE_IDENTITY_DISABLE_MULTITENANTAUTH` environment variable.
- Removed support for specific Azure regions on `ClientSecretCredential` and `ClientCertificateCredential. This feature will be added back on the next beta.

#### Breaking Changes from 2.0.0-beta.6

- Renamed the `ApplicationCredential` to `AzureApplicationCredential`.
- Removed the `CredentialPersistenceOptions` from `DefaultAzureCredential` and `EnvironmentCredential`.
- Merged the configuration and the options bag on the `OnBehalfOfCredential` into a single options bag.

### Bugs Fixed

- `ClientSecretCredential`, `ClientCertificateCredential`, and `UsernamePasswordCredential` throw if the required parameters aren't provided (even in JavaScript).
Expand Down
2 changes: 1 addition & 1 deletion sdk/identity/identity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"./dist-esm/src/credentials/visualStudioCodeCredential.js": "./dist-esm/src/credentials/visualStudioCodeCredential.browser.js",
"./dist-esm/src/credentials/usernamePasswordCredential.js": "./dist-esm/src/credentials/usernamePasswordCredential.browser.js",
"./dist-esm/src/credentials/azurePowerShellCredential.js": "./dist-esm/src/credentials/azurePowerShellCredential.browser.js",
"./dist-esm/src/credentials/applicationCredential.js": "./dist-esm/src/credentials/applicationCredential.browser.js",
"./dist-esm/src/credentials/azureApplicationCredential.js": "./dist-esm/src/credentials/azureApplicationCredential.browser.js",
"./dist-esm/src/credentials/onBehalfOfCredential.js": "./dist-esm/src/credentials/onBehalfOfCredential.browser.js",
"./dist-esm/src/util/authHostEnv.js": "./dist-esm/src/util/authHostEnv.browser.js",
"./dist-esm/src/util/validateMultiTenant.js": "./dist-esm/src/util/validateMultiTenant.browser.js",
Expand Down
39 changes: 20 additions & 19 deletions sdk/identity/identity/review/identity.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class AuthorizationCodeCredential implements TokenCredential {
constructor(tenantId: string | "common", clientId: string, clientSecret: string, authorizationCode: string, redirectUri: string, options?: TokenCredentialOptions);
constructor(tenantId: string | "common", clientId: string, authorizationCode: string, redirectUri: string, options?: TokenCredentialOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
}

// @public
export enum AzureAuthorityHosts {
Expand All @@ -78,7 +78,7 @@ export enum AzureAuthorityHosts {
export class AzureCliCredential implements TokenCredential {
constructor(options?: AzureCliCredentialOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
}

// @public
export interface AzureCliCredentialOptions extends TokenCredentialOptions {
Expand All @@ -89,7 +89,7 @@ export interface AzureCliCredentialOptions extends TokenCredentialOptions {
export class AzurePowerShellCredential implements TokenCredential {
constructor(options?: AzurePowerShellCredentialOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
}

// @public
export interface AzurePowerShellCredentialOptions extends TokenCredentialOptions {
Expand All @@ -110,7 +110,7 @@ export class ChainedTokenCredential implements TokenCredential {
export class ClientCertificateCredential implements TokenCredential {
constructor(tenantId: string, clientId: string, certificatePath: string, options?: ClientCertificateCredentialOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
}

// @public
export interface ClientCertificateCredentialOptions extends TokenCredentialOptions, CredentialPersistenceOptions {
Expand All @@ -121,7 +121,7 @@ export interface ClientCertificateCredentialOptions extends TokenCredentialOptio
export class ClientSecretCredential implements TokenCredential {
constructor(tenantId: string, clientId: string, clientSecret: string, options?: ClientSecretCredentialOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
}

// @public
export interface ClientSecretCredentialOptions extends TokenCredentialOptions, CredentialPersistenceOptions {
Expand All @@ -146,7 +146,7 @@ export class DefaultAzureCredential extends ChainedTokenCredential {
}

// @public
export interface DefaultAzureCredentialOptions extends TokenCredentialOptions, CredentialPersistenceOptions {
export interface DefaultAzureCredentialOptions extends TokenCredentialOptions {
managedIdentityClientId?: string;
tenantId?: string;
}
Expand All @@ -159,7 +159,7 @@ export class DeviceCodeCredential implements TokenCredential {
constructor(options?: DeviceCodeCredentialOptions);
authenticate(scopes: string | string[], options?: GetTokenOptions): Promise<AuthenticationRecord | undefined>;
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
}

// @public
export interface DeviceCodeCredentialOptions extends InteractiveCredentialOptions, CredentialPersistenceOptions {
Expand All @@ -185,7 +185,7 @@ export class EnvironmentCredential implements TokenCredential {
}

// @public
export interface EnvironmentCredentialOptions extends TokenCredentialOptions, CredentialPersistenceOptions {
export interface EnvironmentCredentialOptions extends TokenCredentialOptions {
}

// @public
Expand All @@ -211,7 +211,7 @@ export class InteractiveBrowserCredential implements TokenCredential {
constructor(options?: InteractiveBrowserCredentialOptions | InteractiveBrowserCredentialBrowserOptions);
authenticate(scopes: string | string[], options?: GetTokenOptions): Promise<AuthenticationRecord | undefined>;
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
}

// @public
export interface InteractiveBrowserCredentialBrowserOptions extends InteractiveCredentialOptions {
Expand Down Expand Up @@ -244,31 +244,33 @@ export class ManagedIdentityCredential implements TokenCredential {
constructor(clientId: string, options?: TokenCredentialOptions);
constructor(options?: TokenCredentialOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
}

// @public
export class OnBehalfOfCredential implements TokenCredential {
constructor(configuration: OnBehalfOfCredentialSecretConfiguration | OnBehalfOfCredentialCertificateConfiguration, options?: OnBehalfOfCredentialOptions);
constructor(options: OnBehalfOfCredentialOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
}

// @public
export interface OnBehalfOfCredentialCertificateConfiguration {
export interface OnBehalfOfCredentialCertificateOptions {
certificatePath: string;
clientId: string;
clientSecret?: never;
sendCertificateChain?: boolean;
tenantId: string;
userAssertionToken: string;
}

// @public
export interface OnBehalfOfCredentialOptions extends TokenCredentialOptions, CredentialPersistenceOptions {
}
export type OnBehalfOfCredentialOptions = (OnBehalfOfCredentialSecretOptions | OnBehalfOfCredentialCertificateOptions) & TokenCredentialOptions & CredentialPersistenceOptions;

// @public
export interface OnBehalfOfCredentialSecretConfiguration {
export interface OnBehalfOfCredentialSecretOptions {
certificatePath?: never;
clientId: string;
clientSecret: string;
sendCertificateChain?: never;
tenantId: string;
userAssertionToken: string;
}
Expand Down Expand Up @@ -297,7 +299,7 @@ export function useIdentityPlugin(plugin: IdentityPlugin): void;
export class UsernamePasswordCredential implements TokenCredential {
constructor(tenantId: string, clientId: string, username: string, password: string, options?: UsernamePasswordCredentialOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
}

// @public
export interface UsernamePasswordCredentialOptions extends TokenCredentialOptions, CredentialPersistenceOptions {
Expand All @@ -307,14 +309,13 @@ export interface UsernamePasswordCredentialOptions extends TokenCredentialOption
export class VisualStudioCodeCredential implements TokenCredential {
constructor(options?: VisualStudioCodeCredentialOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
}

// @public
export interface VisualStudioCodeCredentialOptions extends TokenCredentialOptions {
tenantId?: string;
}


// (No @packageDocumentation comment for this package)

```
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ const logger = credentialLogger("ApplicationCredential");
*
* Only available in Node.js
*/
export class ApplicationCredential extends ChainedTokenCredential {
export class AzureApplicationCredential extends ChainedTokenCredential {
/**
* Creates an instance of the ApplicationCredential class.
* Creates an instance of the AzureApplicationCredential class.
*
* The ApplicationCredential provides a default {@link ChainedTokenCredential} configuration for
* The AzureApplicationCredential provides a default {@link ChainedTokenCredential} configuration for
* applications that will be deployed to Azure.
*
* Only available in Node.js
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import { CredentialPersistenceOptions } from "./credentialPersistenceOptions";
import { DefaultManagedIdentityCredential } from "./defaultAzureCredential";

/**
* Provides options to configure the {@link ApplicationCredential} class.
* Provides options to configure the {@link AzureApplicationCredential} class.
*/
export interface ApplicationCredentialOptions
export interface AzureApplicationCredentialOptions
extends TokenCredentialOptions,
CredentialPersistenceOptions {
/**
Expand All @@ -28,11 +28,11 @@ export interface ApplicationCredentialOptions
* The type of a class that implements TokenCredential and accepts
* `ApplicationCredentialOptions`.
*/
interface ApplicationCredentialConstructor {
new (options?: ApplicationCredentialOptions): TokenCredential;
interface AzureApplicationCredentialConstructor {
new (options?: AzureApplicationCredentialOptions): TokenCredential;
}

export const ApplicationCredentials: ApplicationCredentialConstructor[] = [
export const AzureApplicationCredentials: AzureApplicationCredentialConstructor[] = [
EnvironmentCredential,
DefaultManagedIdentityCredential
];
Expand All @@ -41,11 +41,11 @@ export const ApplicationCredentials: ApplicationCredentialConstructor[] = [
* Provides a default {@link ChainedTokenCredential} configuration that should
* work for most applications that use the Azure SDK.
*/
export class ApplicationCredential extends ChainedTokenCredential {
export class AzureApplicationCredential extends ChainedTokenCredential {
/**
* Creates an instance of the ApplicationCredential class.
* Creates an instance of the AzureApplicationCredential class.
*
* The ApplicationCredential provides a default {@link ChainedTokenCredential} configuration that should
* The AzureApplicationCredential provides a default {@link ChainedTokenCredential} configuration that should
* work for most applications that use the Azure SDK. The following credential
* types will be tried, in order:
*
Expand All @@ -55,10 +55,10 @@ export class ApplicationCredential extends ChainedTokenCredential {
* Consult the documentation of these credential types for more information
* on how they attempt authentication.
*
* @param options - Optional parameters. See {@link ApplicationCredentialOptions}.
* @param options - Optional parameters. See {@link AzureApplicationCredentialOptions}.
*/
constructor(options?: ApplicationCredentialOptions) {
super(...ApplicationCredentials.map((ctor) => new ctor(options)));
constructor(options?: AzureApplicationCredentialOptions) {
super(...AzureApplicationCredentials.map((ctor) => new ctor(options)));
this.UnavailableMessage =
"ApplicationCredential => failed to retrieve a token from the included credentials";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,12 @@ import { AzureCliCredential } from "./azureCliCredential";
import { AzurePowerShellCredential } from "./azurePowerShellCredential";
import { EnvironmentCredential } from "./environmentCredential";
import { ManagedIdentityCredential } from "./managedIdentityCredential";
import { CredentialPersistenceOptions } from "./credentialPersistenceOptions";
import { VisualStudioCodeCredential } from "./visualStudioCodeCredential";

/**
* Provides options to configure the {@link DefaultAzureCredential} class.
*/
export interface DefaultAzureCredentialOptions
extends TokenCredentialOptions,
CredentialPersistenceOptions {
export interface DefaultAzureCredentialOptions extends TokenCredentialOptions {
/**
* Optionally pass in a Tenant ID to be used as part of the credential.
* By default it may use a generic tenant ID depending on the underlying credential.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { checkTenantId } from "../util/checkTenantId";
import { trace } from "../util/tracing";
import { ClientCertificateCredential } from "./clientCertificateCredential";
import { UsernamePasswordCredential } from "./usernamePasswordCredential";
import { CredentialPersistenceOptions } from "./credentialPersistenceOptions";

/**
* Contains the list of all supported environment variable names so that an
Expand All @@ -35,9 +34,7 @@ const logger = credentialLogger("EnvironmentCredential");
* Enables authentication to Azure Active Directory depending on the available environment variables.
* Defines options for the EnvironmentCredential class.
*/
export interface EnvironmentCredentialOptions
extends TokenCredentialOptions,
CredentialPersistenceOptions {}
export interface EnvironmentCredentialOptions extends TokenCredentialOptions {}

/**
* Enables authentication to Azure Active Directory using client secret
Expand Down
77 changes: 10 additions & 67 deletions sdk/identity/identity/src/credentials/onBehalfOfCredential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,15 @@ import { MsalOnBehalfOf } from "../msal/nodeFlows/msalOnBehalfOf";
import { credentialLogger } from "../util/logging";
import { trace } from "../util/tracing";
import { MsalFlow } from "../msal/flows";
import { OnBehalfOfCredentialOptions } from "./onBehalfOfCredentialOptions";
import {
OnBehalfOfCredentialCertificateOptions,
OnBehalfOfCredentialOptions,
OnBehalfOfCredentialSecretOptions
} from "./onBehalfOfCredentialOptions";

const credentialName = "OnBehalfOfCredential";
const logger = credentialLogger(credentialName);

/**
* Defines the configuration parameters to authenticate the {@link OnBehalfOfCredential} with a secret.
*/
export interface OnBehalfOfCredentialSecretConfiguration {
/**
* The Azure Active Directory tenant (directory) ID.
*/
tenantId: string;
/**
* The client (application) ID of an App Registration in the tenant.
*/
clientId: string;
/**
* A client secret that was generated for the App Registration.
*/
clientSecret: string;
/**
* The user assertion for the On-Behalf-Of flow.
*/
userAssertionToken: string;
}

/**
* Defines the configuration parameters to authenticate the {@link OnBehalfOfCredential} with a certificate.
*/
export interface OnBehalfOfCredentialCertificateConfiguration {
/**
* The Azure Active Directory tenant (directory) ID.
*/
tenantId: string;
/**
* The client (application) ID of an App Registration in the tenant.
*/
clientId: string;
/**
* The path to a PEM-encoded public/private key certificate on the filesystem.
*/
certificatePath: string;
/**
* Option to include x5c header for SubjectName and Issuer name authorization.
* Set this option to send base64 encoded public certificate in the client assertion header as an x5c claim
*/
sendCertificateChain?: boolean;
/**
* The user assertion for the On-Behalf-Of flow.
*/
userAssertionToken: string;
}

/**
* Enables authentication to Azure Active Directory using the [On Behalf Of flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).
*/
Expand All @@ -86,31 +41,19 @@ export class OnBehalfOfCredential implements TokenCredential {
* await client.getKey("key-name");
* ```
*
* @param configuration - Configuration specific to this credential.
* @param options - Optional parameters, generally common across credentials.
*/
constructor(
private configuration:
| OnBehalfOfCredentialSecretConfiguration
| OnBehalfOfCredentialCertificateConfiguration,
private options: OnBehalfOfCredentialOptions = {}
) {
const { tenantId, clientId, userAssertionToken } = configuration;
const secretConfiguration = configuration as OnBehalfOfCredentialSecretConfiguration;
const certificateConfiguration = configuration as OnBehalfOfCredentialCertificateConfiguration;
if (
!tenantId ||
!clientId ||
!(secretConfiguration.clientSecret || certificateConfiguration.certificatePath) ||
!userAssertionToken
) {
constructor(private options: OnBehalfOfCredentialOptions) {
const { clientSecret } = options as OnBehalfOfCredentialSecretOptions;
const { certificatePath } = options as OnBehalfOfCredentialCertificateOptions;
const { tenantId, clientId, userAssertionToken } = options;
if (!tenantId || !clientId || !(clientSecret || certificatePath) || !userAssertionToken) {
throw new Error(
`${credentialName}: tenantId, clientId, clientSecret (or certificatePath) and userAssertionToken are required parameters.`
);
}
this.msalFlow = new MsalOnBehalfOf({
...this.options,
...this.configuration,
logger,
tokenCredentialOptions: this.options
});
Expand Down
Loading

0 comments on commit 5a8cb4c

Please sign in to comment.