Skip to content

The provided ConfidentialClientApplicationOptions.RedirectUri is not honored when Web App requests access token for the downstream API #784

Description

@vh-vahan

Which version of Microsoft Identity Web are you using?
Note that to get help, you need to run the latest version.
Microsoft Identity Web 1.3.0

Where is the issue?

  • Web app
    • Sign-in users
    • Sign-in users and call web APIs
  • Web API
    • Protected web APIs (validating tokens)
    • Protected web APIs (validating scopes)
    • Protected web APIs call downstream web APIs
  • Token cache serialization
    • In-memory caches
    • Session caches
    • Distributed caches
  • Other (please describe)

Is this a new or an existing app?
This is a new app in development

Repro

services.AddAuthentication("OpenIdConnect")
	.AddMicrosoftIdentityWebApp(
		msIdentityOptions =>
		{
			msIdentityOptions.ClientId = myWebAppClientId;
			msIdentityOptions.Scope.Add(myWebApiScope);

			msIdentityOptions.Events.OnRedirectToIdentityProvider = context =>
			{
				context.ProtocolMessage.RedirectUri = clusterLoadBalancedUri;
				return Task.CompletedTask;
			};

			msIdentityOptions.Instance = Instance;
			msIdentityOptions.Domain = Domain;
			msIdentityOptions.TenantId = TenantId;
                        .........
		})
	.EnableTokenAcquisitionToCallDownstreamApi(
		confidentialClientApplicationOptions =>
		{
			confidentialClientApplicationOptions.RedirectUri = clusterLoadBalancedUri;

			confidentialClientApplicationOptions.ClientId = myWebAppClientId;
			confidentialClientApplicationOptions.Instance = Instance;
			confidentialClientApplicationOptions.TenantId = TenantId;
		})
	.AddInMemoryTokenCaches();

Expected behavior
confidentialClientApplicationOptions.RedirectUri is used when provided.

Actual behavior
I have an ASP.NET Core web app that calls a downstream web API, and being deployed into Service Fabric cluster. The Web App's redirect URI in app registration portal is configured to be the load balanced URI of the cluster and also localhost.

It works on local environment when the app is deployed locally.
But I get exception when it runs on the cluster -

Exception occurred while processing the request.
System.Exception: An error was encountered while handling the remote login.
---> MSAL.NetCore.4.18.0.0.MsalServiceException:
ErrorCode: invalid_client
Microsoft.Identity.Client.MsalServiceException: A configuration issue is preventing authentication - check the error message from the server for details.You can modify the configuration in the application registration portal.
Original exception: AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application: "my app id".

at Microsoft.Identity.Client.OAuth2.OAuth2Client.ThrowServerException(HttpResponse response, RequestContext requestContext)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.CreateResponse[T](HttpResponse response, RequestContext requestContext)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.ExecuteRequestAsync[T](Uri endPoint, HttpMethod method, RequestContext requestContext, Boolean expectErrorsOn200OK, Boolean addCommonHeaders)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.GetTokenAsync(Uri endPoint, RequestContext requestContext, Boolean addCommonHeaders)
at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint)
at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint)
at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(String tokenEndpoint, IDictionary2 additionalBodyParameters, CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.ConfidentialAuthCodeRequest.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.ApiConfig.Executors.ConfidentialClientExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenByAuthorizationCodeParameters authorizationCodeParameters, CancellationToken cancellationToken)
at Microsoft.Identity.Web.TokenAcquisition.AddAccountToCacheFromAuthorizationCodeAsync(AuthorizationCodeReceivedContext context, IEnumerable`1 scopes)
at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>c__DisplayClass10_1.<b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.RunAuthorizationCodeReceivedEventAsync(OpenIdConnectMessage authorizationResponse, ClaimsPrincipal user, AuthenticationProperties properties, JwtSecurityToken jwt)
at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleRemoteAuthenticateAsync()
StatusCode: 400
ResponseBody: {"error":"invalid_client","error_description":"AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application: 'my app id'.}

--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)

I think confidentialClientApplicationOptions.RedirectUri is not being honored and instead it uses the redirect uri constructed from the cluster node's IP.

Possible solution

https://github.com/AzureAD/microsoft-identity-web/blob/9bdf816d2f0e8fd029328ad11cf33217da963ba9/src/Microsoft.Identity.Web/TokenAcquisition.cs#L470
TokenAcquisition. BuildConfidentialClientApplicationAsync method checks for the configured redirectUri.

Additional context / logs / screenshots
Add any other context about the problem here, such as logs and screenshots.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions