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] Cleanups #18532

Merged
merged 35 commits into from
Nov 6, 2021
Merged

[Identity] Cleanups #18532

merged 35 commits into from
Nov 6, 2021

Conversation

sadasant
Copy link
Contributor

@sadasant sadasant commented Nov 4, 2021

This PR contains several cleanups on the Identity project. These include:

  • Moved the test/manual files to test/manual/interactive-browser-credential.
  • samples/manual to test/manual/authorization-code-credential.
  • TokenCredentialOptions to its own file.
  • ManagedIdentityCredential cleanups (mostly that I removed the msiGenericGetToken).
  • Very small cleanups on the credentials (mostly comments).
  • MSAL common files to start with "msal" (msalBrowserCommon, and msalNodeCommon), to make them easier to find. I always had a hard time finding them since they are named differently than the other files in those folders.
  • Removed any types from the internal implementation of the ManagedIdentityCredential.

This PR is part of the work mentioned in #17489 , but it won’t fully solve it.

@sadasant sadasant mentioned this pull request Nov 4, 2021
6 tasks
Copy link
Member

@witemple-msft witemple-msft left a comment

Choose a reason for hiding this comment

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

Some comments where I think extra explanation could be useful or where I think there's some extra code that doesn't necessarily need to be there.

If we're doing code cleanups, could we also just brush over all the uses of any in these files and find better types for them -- even if that's just unknown in some cases?


const msiName = "ManagedIdentityCredential - AppServiceMSI 2017";
const logger = credentialLogger(msiName);

/**
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
*/
function expiresInParser(requestBody: any): number {
Copy link
Member

Choose a reason for hiding this comment

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

This function is expiresIn but the property name is expires_on.

And moreover, do we even need this abstraction (especially given that we have an any type here)? Could we not just replace all calls to expiresInParser(x) with Date.parse(x.expires_on)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Both expires_in and expires_on can exist in the payloads. Expires in meaning how much time is left, and expires on meaning at what time it will expire. We do this transformation on a case by case basis according to the target authentication environment. We try to narrow this down to the expiresOnTimestamp property, so I’ll change the expiresInParser functions to expiresOnParser since on average we use expires.[oO]n more often.

Copy link
Member

Choose a reason for hiding this comment

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

If it's case by case, then I'm just saying that this specific case ought to be expiresOn. I noticed that one of the other MSI instances checks expires_in, but not this one and not several others.

Comment on lines 33 to 36
function expiresInParser(requestBody: any): number {
// Parses a string representation of the seconds since epoch into a number value
return Number(requestBody.expires_on);
}
Copy link
Member

Choose a reason for hiding this comment

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

Same comment here as expiresInParser.

Something doesn't align here. The comment says "seconds since epoch" and the doc comment of the function says "milliseconds since". Which is the actual value and can we just do a parseInt where we need this function instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There’s a default expires on parser function. This case is different. The comment should say “milliseconds since”, so I’ll update that.

Comment on lines +122 to +126
request.agent = new https.Agent({
// This is necessary because Service Fabric provides a self-signed certificate.
// The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
rejectUnauthorized: false
});
Copy link
Member

Choose a reason for hiding this comment

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

This makes me very nervous. Can we try to validate the service fabric cert instead? Is there some kind of technical reason that the cert is self-signed instead of using a real trusted cert?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Service fabric MSI certificates are self-signed since they’re only meant to be reached form the internal network. We have in our roadmaps to strengthen security of this authentication flow, however across languages we have agreed to skip the verification of the certificates. This is a local-network (cluster) endpoint, so it’s not as unsafe as a public domain endpoint, if that helps.

Copy link
Member

Choose a reason for hiding this comment

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

If that's what folks have agreed to do, then I suppose that's OK, but I really wish we could at least check the thumbprint against a list or something. If not, then I guess it's just a limitation of the environment, but still makes me nervous.

import { AuthenticationError } from "../../errors";

const msiName = "ManagedIdentityCredential - IMDS";
const logger = credentialLogger(msiName);

/**
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
*/
function expiresInParser(requestBody: any): number {
Copy link
Member

Choose a reason for hiding this comment

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

Why is this the only copy of this function where we validate the existence of the expires_on property? Also, can we give requestBody an accurate type here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For sure! I’ll give requestBody a type! Thank you for pointing me to this. By this point it was invisible to me that there was an “any” type here.

Copy link
Contributor Author

@sadasant sadasant Nov 5, 2021

Choose a reason for hiding this comment

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

Why is this the only copy of this function where we validate the existence of the expires_on property?

We assume that the other authentication environments will always provide an expires_on property.

In the cases where we don’t have a specific method, we always use expires_in, which should always be present.

const request = createPipelineRequest({
abortSignal: getTokenOptions.abortSignal,
...prepareRequestOptions(scopes, clientId),
allowInsecureConnection: true
Copy link
Member

Choose a reason for hiding this comment

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

I think we ought to document the exact reasoning for any settings like this where we disable an otherwise default security setting.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Most of the IMDS endpoints are http endpoints. The default one is http://169.254.169.254/, but environment variables can specify another endpoint. I will add a comment mentioning this.

const request = createPipelineRequest({
abortSignal: getTokenOptions.abortSignal,
...prepareRequestOptions(scopes, assertion, clientId || process.env.AZURE_CLIENT_ID!),
allowInsecureConnection: true
Copy link
Member

Choose a reason for hiding this comment

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

Same comment about documenting why this is necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IMDS endpoints are http, which are blocked by default by our pipelines.

Copy link
Member

@witemple-msft witemple-msft left a comment

Choose a reason for hiding this comment

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

Every time we remove an any, an angel gets their wings.

@sadasant sadasant enabled auto-merge (squash) November 5, 2021 23:31
witemple-msft and others added 8 commits November 6, 2021 02:36
…18289)

* Initial Rest Client work for Synapse Access Control

* Update ci pipeline

* Update tests

* Update pagination helper and test

* Add samples

* Fix Access Control rest

* Update broken links

* Fix format in agrifood
* Purview Administration

* Purview Catalog

* Purview Account

* Purview scanning

* Farmbeats

* ConfidentialLedger

* DocumentTranslator
Last PR some had 2.0.0 and some 2.0.1. Updating so all of them depend on ^2.0.1
Data was in the incorrect format, fixing it for release
AlonsoMondal and others added 3 commits November 6, 2021 02:37
* added autorest readme and generated files

* rush.json modified and rush update-build ran for communication-short-codes. Imported samples and ran dev-tool for sample creation.

* copied commincation-phone-numbers .gitignore into communication-short-codes

* added README.md for short codes

* fix @azure-tools reference

* removed temporary fix for dist-esm and types files not generated in src subfolder. Previous commit from Erica fixed root issue.

* modified sample to new changes (removed signup and fixed useCase)

* changed createUSProgramBrief to upserUSProgramBrief in README.md - further polishing of readme probably needed

* fixed wrong references to short codes package imports in readme.md

* regenerated from latest swagger

* regenerated from swagger from now merged PR. Added necessary modifications. Pending on a possible swagger mistake, that's why it is not building.

* updated swagger, updated sdk, referencing latest commit in master for swagger.

* built samples

* Added compiling tests with meat but it is VERY RAW. Like the animal is still alive.

* added autorest readme and generated files

* rush.json modified and rush update-build ran for communication-short-codes. Imported samples and ran dev-tool for sample creation.

* copied commincation-phone-numbers .gitignore into communication-short-codes

* added README.md for short codes

* fix @azure-tools reference

* removed temporary fix for dist-esm and types files not generated in src subfolder. Previous commit from Erica fixed root issue.

* modified sample to new changes (removed signup and fixed useCase)

* changed createUSProgramBrief to upserUSProgramBrief in README.md - further polishing of readme probably needed

* fixed wrong references to short codes package imports in readme.md

* regenerated from latest swagger

* regenerated from swagger from now merged PR. Added necessary modifications. Pending on a possible swagger mistake, that's why it is not building.

* updated swagger, updated sdk, referencing latest commit in master for swagger.

* built samples

* Added compiling tests with meat but it is VERY RAW. Like the animal is still alive.

* meat ready to cook

* Regenerated with autorest from latest changes. Swagger now points to Rodolfo

* updated sample from swagger

* unit tests running and passing. unit tests with AAD failing.

* updating tests to get env variables and splitting upsert in update & create

* removed AAD tests

* removed non-existing links to public documentation in sample readmes

* added pnpm-lock.yml for short codes and removed unnecessary imports because of removed AAD tests.

* reverted accidental change

* added short codes to communication ci.yml

* wrapping calls to the generated client in try catch finally blocks. automatic formatting

* refactoring us program brief for better accessing and not to repeat data

* changing let that should be const and unnecessary id check on test USPB retrieval.

* grabbed pnpm-lock.yaml from azure/main and used rush update

* missing pnpm-lock.yaml changes

* fixing lint issues and building

* run rushx format

* fixes for recorded tests

* running rushx format

* added changelog

* ran prepare release script

* resolving comments from PR. Deleting unused variables, fixing references, renaming variables, updating changelog

* run the format command

* Update ci.yml

* Update ci.yml

* trying change from rest to tools

* updating samples

* added missing pnpm-lock.yaml update

* updating release date

Co-authored-by: Erica Sponsler <[email protected]>
Co-authored-by: 0rlanand0Wats0n <[email protected]>
* [ai-form-recognizer] Lazy iterator for words of a line

* Use method instead of property

* Regenerate API

* Polished, wrote changelog, added some more tests, samples

* Updated API MD

* Improved docs

* Apply changes from review
* adding retry to docker container start

Co-authored-by: scbedd <[email protected]>
@sadasant sadasant merged commit 746bb4f into Azure:main Nov 6, 2021
@sadasant sadasant deleted the identity/cleanups branch November 6, 2021 14:29
danieljurek pushed a commit that referenced this pull request Nov 10, 2021
This PR contains several cleanups on the Identity project. These include:

- Moved the `test/manual` files to `test/manual/interactive-browser-credential`.
- `samples/manual` to `test/manual/authorization-code-credential`.
- `TokenCredentialOptions` to its own file.
- `ManagedIdentityCredential` cleanups (mostly that I removed the `msiGenericGetToken`).
- Very small cleanups on the credentials (mostly comments).
- MSAL common files to start with "msal" (`msalBrowserCommon`, and `msalNodeCommon`), to make them easier to find. I always had a hard time finding them since they are named differently than the other files in those folders.
- Removed `any` types from the internal implementation of the `ManagedIdentityCredential`.

This PR is part of the work mentioned in #17489 , but it won’t fully solve it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.