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] Changes after the architects review #18072

Merged
merged 4 commits into from
Oct 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I will do so!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I merged this too soon. I’ll follow up with a separate PR.

- 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