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

Allow applications to bypass network request for OpenID configuration #1578

Merged
merged 11 commits into from May 21, 2020

Conversation

jasonnutter
Copy link
Contributor

@jasonnutter jasonnutter commented Apr 30, 2020

The allows applications to bypass the network request to retrieve the OpenID configuration that is normally fetched on every request. This data must be retrieved from the openid configuration endpoint and passed wholesale as a JSON string.

Steps:

  1. Go to https://login.microsoftonline.com/common/discovery/instance?api-version=1.0&authorization_endpoint={authorizeEndpoint} for your authority: https://login.microsoftonline.com/common/discovery/instance?api-version=1.0&authorization_endpoint=https://login.microsoftonline.com/common/oauth2/v2.0/authorize
  2. Go to the location set as the tenant_discovery_endpoint: https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration

A side-effect of this change is that the library will cache the response and use that for every call for the current session, regardless if it was provided in the configuration or retrieved via a network call.

Before:

Annotation 2020-05-18 141615

After:

Annotation 2020-05-18 141850

TODO:

  • Additional tests
  • Documentation

@jasonnutter jasonnutter marked this pull request as draft April 30, 2020 23:35
@DarylThayil
Copy link
Contributor

made some comments, if we can get those resolved and add error handling + tests lets ship it

@@ -483,13 +484,13 @@ export class UserAgentApplication {
* Helper function to acquireToken
*
*/
private acquireTokenHelper(account: Account, interactionType: InteractionType, isLoginCall: boolean, request: AuthenticationParameters, resolve?: any, reject?: any): void {
private async acquireTokenHelper(account: Account, interactionType: InteractionType, isLoginCall: boolean, request: AuthenticationParameters, resolve?: any, reject?: any): Promise<void> {
Copy link
Member

Choose a reason for hiding this comment

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

Does this effect performance for calls that don't need this async?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Potentially, but should be offset when not making the openid-config call at all. Will verify.

Copy link
Member

@sameerag sameerag left a comment

Choose a reason for hiding this comment

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

Over all looks good. One concern I had is the bubbling up async for the interactive helper function acquireTokenHelper and the impact of performance for operations that do not need async.

…rary-for-js into authority-metadata-openid-perf
@jasonnutter jasonnutter marked this pull request as ready for review May 18, 2020 22:00
@coveralls
Copy link

coveralls commented May 18, 2020

Coverage Status

Coverage increased (+0.05%) to 78.528% when pulling e83b927 on authority-metadata-openid-perf into c70e48b on dev.

@@ -514,7 +515,14 @@ export class UserAgentApplication {
}
}

acquireTokenAuthority.resolveEndpointsAsync(this.telemetryManager, request.correlationId).then(async () => {
try {
if (!acquireTokenAuthority.hasCachedMetadata()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of checking for this here, why don't we just do this inside resolveAuthorityAsync()? If the cached metadata is available, just return it, otherwise make a network request (similar to acquireTokenSilent)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I like this too. Though this would prevent intentional refreshes without an additional forceRefresh parameter. Not sure if there's a valid argument for supporting that use case but something to consider.

Copy link
Contributor

Choose a reason for hiding this comment

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

We can't do intentional refreshes anyway with the current code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One of the goals is to minimize the number of async code paths, which is why the if is done here, so that way if the check fails, we don't enter an async function. If this was factored out, it would enter the async every time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, I did not consider if forceRefresh should force a network call for openid configuration, in addition to forcing a network call for a new token. Initially, I would think not. @DarylThayil any opinion here?

@@ -7,7 +7,12 @@ import { Constants } from "../utils/Constants";
import { ClientAuthError } from "./ClientAuthError";
import { TelemetryOptions } from "../Configuration";

export const ClientConfigurationErrorMessage = {
interface IClientConfigurationErrorMessage {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we making this change for error message classes, and should it be done for all error message classes?

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 felt we should codify the pattern of code/desc in the object below. I would actually complete refactor this into a different pattern, but felt this was an incremental improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants