AzureAD / microsoft-identity-web

Helps creating protected web apps and web APIs with Microsoft identity platform and Azure AD B2C
MIT License
671 stars 208 forks source link

AADSTS54005: OAuth2 Authorization code was already redeemed #2328

Open TejendraPrasad opened 1 year ago

TejendraPrasad commented 1 year ago

Microsoft.Identity.Web Library

Microsoft.Identity.Web

Microsoft.Identity.Web version

2.12.4

Web app

Sign-in users

Web API

Protected web APIs (validating scopes/roles)

Token cache serialization

In-memory caches

Description

.NET CORE 6 MVC

I have upgrade package from 2.11.0 to [2.12.4].. i get below errro

Reproduction steps

User login and it goes infinite loop microsoft.login

Error message

[08:48:36] [Error] [Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler] Exception occurred while processing message. MSAL.NetCore.4.54.1.0.MsalUiRequiredException: ErrorCode: invalid_grant Microsoft.Identity.Client.MsalUiRequiredException: AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token. Trace ID: ce41467c-55bb-40e1-ab95-67f439011200 Correlation ID: a4e9ecc3-e73f-4938-a67c-144d76c96f0e Timestamp: 2023-07-13 07:48:39Z 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, Func2 onBeforePostRequestData) at Microsoft.Identity.Client.OAuth2.OAuth2Client.GetTokenAsync(Uri endPoint, RequestContext requestContext, Boolean addCommonHeaders, Func2 onBeforePostRequestHandler) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(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(AuthCodeRedemptionParameters authCodeRedemptionParameters) at Microsoft.Identity.Web.TokenAcquisitionAspNetCore.AddAccountToCacheFromAuthorizationCodeAsync(AuthorizationCodeReceivedContext context, IEnumerable`1 scopes, String authenticationScheme) at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>cDisplayClass11_1.<b1>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>cDisplayClass11_1.<b1>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_grant","error_description":"AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token. "} Headers: Cache-Control: no-store, no-cache

Id Web logs

No response

Relevant code snippets

services.AddMicrosoftIdentityWebAppAuthentication(Configuration)
                   .EnableTokenAcquisitionToCallDownstreamApi()
                   .AddInMemoryTokenCaches();

 services.Configure<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme, options =>
              {
                  options.Cookie.SameSite = SameSiteMode.None;
                  options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
                  options.Cookie.HttpOnly = true;
                  options.Cookie.IsEssential = true;

                  options.Events.OnSigningIn = async (context) =>
                  {
                      context.Properties.IsPersistent = false;

                      await Task.CompletedTask;
                  };

                  options.AccessDeniedPath = new PathString("/Error/UnAuthorized");
              });

 services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
                {
                    options.MetadataAddress = metadataAddress;
                    options.Authority = authority;
                    options.ClientId = azureAdOptions.ClientId;

                    options.Events.OnTicketReceived = async context =>
                    {
                        context.Properties.IsPersistent = false;
                        await Task.CompletedTask;
                    };

                    var existingOnTokenValidatedHandler = options.Events.OnTokenValidated;

                    options.Events.OnTokenValidated = async context =>
                    {
                        await existingOnTokenValidatedHandler(context);
   await Task.FromResult(0);
                    };
                    options.Events.OnRemoteFailure = async context =>
                    {   await Task.FromResult(0);
                    };
                    options.Events.OnAuthenticationFailed = async (context) =>
                    {  await Task.FromResult(0);
                    };
                });

Regression

2.11.0

Expected behavior

User should be logged in, currently its going infinite loop.

TejendraPrasad commented 1 year ago

I user below code to get access token for secured API

public async Task<string> GetAccessTokenForApplicationAsync(string scope) { return await _tokenAcquisition.GetAccessTokenForAppAsync(scope);}

AndreErb commented 11 months ago

Exactly the same error here. In all our Blazor-Apps / .NET 6 / MS.Identity.Web V2.13.4

This is becoming critical, as restarting the Web-App is the only solution. Additionally, users sometimes have too delete their cookies, after the App has been restarted, cause the failing logins create many cookies behind the scenes. So this makes it additional painful.

@jmprieur @jennyf19 I have a strong feeling, that this problem is related to "Race Condition"-Problem regarding the "Options", though it shows up in different "flavours" (Exceptions):

Other issues (which seem related, but closed): https://github.com/AzureAD/microsoft-identity-web/issues/1995 https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/issues/664 https://github.com/AzureAD/microsoft-identity-web/issues/1957 https://github.com/microsoftgraph/msgraph-sdk-java/issues/977 https://github.com/AzureAD/microsoft-identity-web/issues/2456

We still see it in our APIs as mentioned here. I have seen you guys pointing to .NET 7, but please note that we running on .NET 6 Also the proposed Workaround doesn't seem to be a good option, since in best case it would only hide the real problem.

Our setup in the app looks like this var initialScopes = builder.Configuration["MicrosoftGraph:Scopes"]?.Split(' '); services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph")) .AddDownstreamApi(ApiServiceName, builder.Configuration.GetSection("Api")).AddInMemoryTokenCaches();

Log:

2023-09-27T15:31:14.8689431+02:00 [ERR] (Microsoft.Identity.Web.TokenAcquisition) False MSAL 4.56.0.0 MSAL.NetCore .NET 6.0.14 Microsoft Windows 10.0.17763 [2023-09-27 13:31:14Z - 3bd1f709-ca5d-4119-96b9-57ce20f5ba97] === Token Acquisition (1000) failed.
    Host: login.microsoftonline.com.
2023-09-27T15:31:14.8690196+02:00 [ERR] (Microsoft.Identity.Web.TokenAcquisition) False MSAL 4.56.0.0 MSAL.NetCore .NET 6.0.14 Microsoft Windows 10.0.17763 [2023-09-27 13:31:14Z - 3bd1f709-ca5d-4119-96b9-57ce20f5ba97] Exception type: Microsoft.Identity.Client.MsalUiRequiredException
, ErrorCode: invalid_grant
HTTP StatusCode 400
CorrelationId 3bd1f709-ca5d-4119-96b9-57ce20f5ba97

2023-09-27T15:31:14.8701773+02:00 [ERR] (Microsoft.Identity.Web.TokenAcquisition) False MSAL 4.56.0.0 MSAL.NetCore .NET 6.0.14 Microsoft Windows 10.0.17763 [2023-09-27 13:31:14Z - 3bd1f709-ca5d-4119-96b9-57ce20f5ba97] Exception type: Microsoft.Identity.Client.MsalUiRequiredException
, ErrorCode: invalid_grant
HTTP StatusCode 400
CorrelationId 3bd1f709-ca5d-4119-96b9-57ce20f5ba97

   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, Func`2 onBeforePostRequestData)
   at Microsoft.Identity.Client.OAuth2.OAuth2Client.GetTokenAsync(Uri endPoint, RequestContext requestContext, Boolean addCommonHeaders, Func`2 onBeforePostRequestHandler)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary`2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(IDictionary`2 additionalBodyParameters, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.ConfidentialAuthCodeRequest.ExecuteAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
2023-09-27T15:31:14.8705754+02:00 [ERR] (Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler) Exception occurred while processing message.
MSAL.NetCore.4.56.0.0.MsalUiRequiredException: 
    ErrorCode: invalid_grant
Microsoft.Identity.Client.MsalUiRequiredException: AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token.
Trace ID: 7dff5831-4397-4c81-bd67-fdfc8bba1000
Correlation ID: 3bd1f709-ca5d-4119-96b9-57ce20f5ba97
Timestamp: 2023-09-27 13:31:14Z
   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, Func`2 onBeforePostRequestData)
   at Microsoft.Identity.Client.OAuth2.OAuth2Client.GetTokenAsync(Uri endPoint, RequestContext requestContext, Boolean addCommonHeaders, Func`2 onBeforePostRequestHandler)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary`2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(IDictionary`2 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(AuthCodeRedemptionParameters authCodeRedemptionParameters)
   at Microsoft.Identity.Web.TokenAcquisitionAspNetCore.AddAccountToCacheFromAuthorizationCodeAsync(AuthorizationCodeReceivedContext context, IEnumerable`1 scopes, String authenticationScheme)
   at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>c__DisplayClass11_1.<<WebAppCallsWebApiImplementation>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>c__DisplayClass11_1.<<WebAppCallsWebApiImplementation>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_grant","error_description":"AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token.\r\nTrace ID: 7dff5831-4397-4c81-bd67-fdfc8bba1000\r\nCorrelation ID: 3bd1f709-ca5d-4119-96b9-57ce20f5ba97\r\nTimestamp: 2023-09-27 13:31:14Z","error_codes":[54005],"timestamp":"2023-09-27 13:31:14Z","trace_id":"7dff5831-4397-4c81-bd67-fdfc8bba1000","correlation_id":"3bd1f709-ca5d-4119-96b9-57ce20f5ba97"} 
    Headers: Cache-Control: no-store, no-cache
Pragma: no-cache
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
client-request-id: 3bd1f709-ca5d-4119-96b9-57ce20f5ba97
x-ms-request-id: 7dff5831-4397-4c81-bd67-fdfc8bba1000
x-ms-ests-server: 2.1.16424.6 - WEULR1 ProdSlices
x-ms-clitelem: 1,54005,0,,
X-XSS-Protection: 0
Set-Cookie: fpc=ApnMXQjg__FAkm4RgxMIOt4SbphfDAAAAG4lptwOAAAAbZKiARQAAACWJabcDgAAAA; expires=Fri, 27-Oct-2023 13:31:14 GMT; path=/; secure; HttpOnly; SameSite=None, x-ms-gateway-slice=estsfd; path=/; secure; httponly
Date: Wed, 27 Sep 2023 13:31:13 GMT

2023-09-27T15:31:14.8712050+02:00 [ERR] (Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware) An unhandled exception has occurred while executing the request.
System.Exception: An error was encountered while handling the remote login.
 ---> MSAL.NetCore.4.56.0.0.MsalUiRequiredException: 
    ErrorCode: invalid_grant
Microsoft.Identity.Client.MsalUiRequiredException: AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token.
Trace ID: 7dff5831-4397-4c81-bd67-fdfc8bba1000
Correlation ID: 3bd1f709-ca5d-4119-96b9-57ce20f5ba97
Timestamp: 2023-09-27 13:31:14Z
   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, Func`2 onBeforePostRequestData)
   at Microsoft.Identity.Client.OAuth2.OAuth2Client.GetTokenAsync(Uri endPoint, RequestContext requestContext, Boolean addCommonHeaders, Func`2 onBeforePostRequestHandler)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary`2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(IDictionary`2 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(AuthCodeRedemptionParameters authCodeRedemptionParameters)
   at Microsoft.Identity.Web.TokenAcquisitionAspNetCore.AddAccountToCacheFromAuthorizationCodeAsync(AuthorizationCodeReceivedContext context, IEnumerable`1 scopes, String authenticationScheme)
   at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>c__DisplayClass11_1.<<WebAppCallsWebApiImplementation>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>c__DisplayClass11_1.<<WebAppCallsWebApiImplementation>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_grant","error_description":"AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token.\r\nTrace ID: 7dff5831-4397-4c81-bd67-fdfc8bba1000\r\nCorrelation ID: 3bd1f709-ca5d-4119-96b9-57ce20f5ba97\r\nTimestamp: 2023-09-27 13:31:14Z","error_codes":[54005],"timestamp":"2023-09-27 13:31:14Z","trace_id":"7dff5831-4397-4c81-bd67-fdfc8bba1000","correlation_id":"3bd1f709-ca5d-4119-96b9-57ce20f5ba97"} 
    Headers: Cache-Control: no-store, no-cache
Pragma: no-cache
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
client-request-id: 3bd1f709-ca5d-4119-96b9-57ce20f5ba97
x-ms-request-id: 7dff5831-4397-4c81-bd67-fdfc8bba1000
x-ms-ests-server: 2.1.16424.6 - WEULR1 ProdSlices
x-ms-clitelem: 1,54005,0,,
X-XSS-Protection: 0
Set-Cookie: fpc=ApnMXQjg__FAkm4RgxMIOt4SbphfDAAAAG4lptwOAAAAbZKiARQAAACWJabcDgAAAA; expires=Fri, 27-Oct-2023 13:31:14 GMT; path=/; secure; HttpOnly; SameSite=None, x-ms-gateway-slice=estsfd; path=/; secure; httponly
Date: Wed, 27 Sep 2023 13:31:13 GMT

   --- 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.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
jrmcdona commented 11 months ago

Also having this issue on .NET 6 and Microsoft.Identity.Web 2.14.0

        ```

//configure OIDC providers ConfigureOpenIdConnectOptions(services, configuration, OpenIdConnectDefaults.AuthenticationScheme);

        // configure OIDC authentication with cookie persistence
        services
            .AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
            .AddMicrosoftIdentityWebApp(
                microsoftIdentityOptions => {
                    configuration2.Bind("AAD", microsoftIdentityOptions);
                    microsoftIdentityOptions.ClientCertificates = new CertificateDescription[] {
                        CertificateDescription.FromKeyVault("",
                                     "")  //https://github.com/AzureAD/microsoft-identity-web/wiki/Certificates#specifying-certificates
                    };
            })
            .EnableTokenAcquisitionToCallDownstreamApi(new string[] { "" })  //Scope for the Shell Header service
             .AddDownstreamApi("SuiteShellAPI", configuration2.GetSection("SuiteShellService"))
                 .AddInMemoryTokenCaches();
jmprieur commented 11 months ago

@jrmcdona : I believe that your issue will be fixed by this PR: https://github.com/AzureAD/microsoft-identity-web/pull/2489 Are you able to test? (building from the repo)?

TejendraPrasad commented 11 months ago

@jmprieur thank you for fixing this.

I have updated package version to 2.15.1 and deployed it.

Will keep and eye and update you regarding this any error logs occur.

AndreErb commented 11 months ago

@TejendraPrasad @jmprieur We gave V2.15.2 a try today and still got the same error.

However, we are not using the "AddMicrosoftIdentityWebApp" extension method with "microsoftIdentityOptions " like @jrmcdona does. So the new version could not help us, right?!?

We use

var initialScopes = builder.Configuration["MicrosoftGraph:Scopes"]?.Split(' ');
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
    .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
    .AddDownstreamApi(licenseService, builder.Configuration.GetSection("xxxApi"))
    .AddInMemoryTokenCaches();
TejendraPrasad commented 11 months ago

@AndreErb, thank you! i am yet not sure it has solved.. just today updated nuget package and deployed in Live... so will monitor the changes...

Note When implementing the Microsoft.Identity.Web as the OIDC client, designed explicitly for Azure AD and Azure B2C, it is vital to include the necessary configuration within the MicrosoftIdentityOptions. Failing to do so may result in the not working of downstream APIs. Conversely, if OpenID Connect is used directly, with a distinct Identity Provider (IDP), it is essential to incorporate the OpenIdConnectOptions configuration. These configurations should be integrated into the services of the ASP.NET Core application for seamless functionality.

@jmprieur - can only correct my understanding...

I use OpenIdConnectOptions and CookieAuthenticationOptions options not MicrosoftIdentityOptions...

Yes, i use below for SignIn

services.AddMicrosoftIdentityWebAppAuthentication(Configuration) .EnableTokenAcquisitionToCallDownstreamApi() .AddInMemoryTokenCaches();

And, I access .NET Custom API on behalf of App

return await _tokenAcquisition.GetAccessTokenForAppAsync(scope);

And, for Graph i use SDK

Microsoft.Graph

var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);

_graphServiceClient = new GraphServiceClient(clientSecretCredential, scopes);

AndreErb commented 11 months ago

When implementing the Microsoft.Identity.Web as the OIDC client, designed explicitly for Azure AD and Azure B2C, it is vital to include the necessary configuration within the MicrosoftIdentityOptions. Failing to do so may result in the not working of downstream APIs. Conversely, if OpenID Connect is used directly, with a distinct Identity Provider (IDP), it is essential to incorporate the OpenIdConnectOptions configuration

@TejendraPrasad What exactly are you referring to, in regards to the MicrosoftIdentityOptions? Usually we do not use these options at all and didn't have an issue with our Downstream APIs.

TejendraPrasad commented 11 months ago

@AndreErb, I apologise for any misunderstanding, Please ignore my comments.. :-)

For me the latest version hasn't yet created any problems, but I'll wait a few more days.

TejendraPrasad commented 10 months ago

@jmprieur

I am getting same error "AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token." after updating Version to 2.15.2.0.. It was fine for 1 month....

09:53:35] [Error] [Microsoft.Identity.Web.TokenAcquisition] False MSAL 4.56.0.0 MSAL.NetCore .NET 6.0.15 Microsoft Windows 10.0.17763 [2023-11-17 09:53:35Z - 77da2591-ddf7-40c0-adf6-c6ccf4c43238] Exception type: Microsoft.Identity.Client.MsalUiRequiredException , ErrorCode: invalid_grant HTTP StatusCode 400 CorrelationId 77da2591-ddf7-40c0-adf6-c6ccf4c43238

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, Func2 onBeforePostRequestData) at Microsoft.Identity.Client.OAuth2.OAuth2Client.GetTokenAsync(Uri endPoint, RequestContext requestContext, Boolean addCommonHeaders, Func2 onBeforePostRequestHandler) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.ConfidentialAuthCodeRequest.ExecuteAsync(CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken) [09:53:35] [Error] [Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler] Exception occurred while processing message. MSAL.NetCore.4.56.0.0.MsalUiRequiredException: ErrorCode: invalid_grant Microsoft.Identity.Client.MsalUiRequiredException: AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token. Trace ID: ecd07edb-bb52-4b2b-8c15-ee2f7f4e2600 Correlation ID: 77da2591-ddf7-40c0-adf6-c6ccf4c43238 Timestamp: 2023-11-17 09:53:36Z 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, Func2 onBeforePostRequestData) at Microsoft.Identity.Client.OAuth2.OAuth2Client.GetTokenAsync(Uri endPoint, RequestContext requestContext, Boolean addCommonHeaders, Func2 onBeforePostRequestHandler) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(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(AuthCodeRedemptionParameters authCodeRedemptionParameters) at Microsoft.Identity.Web.TokenAcquisitionAspNetCore.AddAccountToCacheFromAuthorizationCodeAsync(AuthorizationCodeReceivedContext context, IEnumerable`1 scopes, String authenticationScheme) at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>cDisplayClass11_1.<b1>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>cDisplayClass11_1.<b1>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_grant","error_description":"AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token. Trace ID: ecd07edb-bb52-4b2b-8c15-ee2f7f4e2600 Correlation ID: 77da2591-ddf7-40c0-adf6-c6ccf4c43238 Timestamp: 2023-11-17 09:53:36Z","error_codes":[54005],"timestamp":"2023-11-17 09:53:36Z","trace_id":"ecd07edb-bb52-4b2b-8c15-ee2f7f4e2600","correlation_id":"77da2591-ddf7-40c0-adf6-c6ccf4c43238"} Headers: Cache-Control: no-store, no-cache Pragma: no-cache Strict-Transport-Security: max-age=31536000; includeSubDomains X-Content-Type-Options: nosniff P3P: CP="DSP CUR OTPi IND OTRi ONL FIN" client-request-id: 77da2591-ddf7-40c0-adf6-c6ccf4c43238 x-ms-request-id: ecd07edb-bb52-4b2b-8c15-ee2f7f4e2600 x-ms-ests-server: 2.1.16729.8 - NEULR1 ProdSlices x-ms-clitelem: 1,54005,0,, X-XSS-Protection: 0 Set-Cookie: fpc=Au0zPikUqa5MqZfs_iUWQWrcAm_7AgAAAB4v6dwOAAAA; expires=Sun, 17-Dec-2023 09:53:36 GMT; path=/; secure; HttpOnly; SameSite=None, x-ms-gateway-slice=estsfd; path=/; secure; httponly Date: Fri, 17 Nov 2023 09:53:35 GMT

[09:53:35] [Error] [] OnAuthenticationFailed AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token. Trace ID: ecd07edb-bb52-4b2b-8c15-ee2f7f4e2600 Correlation ID: 77da2591-ddf7-40c0-adf6-c6ccf4c43238 Timestamp: 2023-11-17 09:53:36Z MSAL.NetCore.4.56.0.0.MsalUiRequiredException: ErrorCode: invalid_grant Microsoft.Identity.Client.MsalUiRequiredException: AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token. Trace ID: ecd07edb-bb52-4b2b-8c15-ee2f7f4e2600 Correlation ID: 77da2591-ddf7-40c0-adf6-c6ccf4c43238 Timestamp: 2023-11-17 09:53:36Z 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, Func2 onBeforePostRequestData) at Microsoft.Identity.Client.OAuth2.OAuth2Client.GetTokenAsync(Uri endPoint, RequestContext requestContext, Boolean addCommonHeaders, Func2 onBeforePostRequestHandler) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(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(AuthCodeRedemptionParameters authCodeRedemptionParameters) at Microsoft.Identity.Web.TokenAcquisitionAspNetCore.AddAccountToCacheFromAuthorizationCodeAsync(AuthorizationCodeReceivedContext context, IEnumerable`1 scopes, String authenticationScheme) at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>cDisplayClass11_1.<b1>d.MoveNext() --- End of stack trace from previous location --- at Microsoft.Identity.Web.MicrosoftIdentityWebAppAuthenticationBuilder.<>cDisplayClass11_1.<b1>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_grant","error_description":"AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token. Trace ID: ecd07edb-bb52-4b2b-8c15-ee2f7f4e2600 Correlation ID: 77da2591-ddf7-40c0-adf6-c6ccf4c43238 Timestamp: 2023-11-17 09:53:36Z","error_codes":[54005],"timestamp":"2023-11-17 09:53:36Z","trace_id":"ecd07edb-bb52-4b2b-8c15-ee2f7f4e2600","correlation_id":"77da2591-ddf7-40c0-adf6-c6ccf4c43238"} Headers: Cache-Control: no-store, no-cache Pragma: no-cache Strict-Transport-Security: max-age=31536000; includeSubDomains X-Content-Type-Options: nosniff P3P: CP="DSP CUR OTPi IND OTRi ONL FIN" client-request-id: 77da2591-ddf7-40c0-adf6-c6ccf4c43238 x-ms-request-id: ecd07edb-bb52-4b2b-8c15-ee2f7f4e2600 x-ms-ests-server: 2.1.16729.8 - NEULR1 ProdSlices x-ms-clitelem: 1,54005,0,, X-XSS-Protection: 0 Set-Cookie: fpc=Au0zPikUqa5MqZfs_iUWQWrcAm_7AgAAAB4v6dwOAAAA; expires=Sun, 17-Dec-2023 09:53:36 GMT; path=/; secure; HttpOnly; SameSite=None, x-ms-gateway-slice=estsfd; path=/; secure; httponly Date: Fri, 17 Nov 2023 09:53:35 GMT

ahiraiwa commented 10 months ago

@jmprieur We are also encountering the same error. Our version of Microsoft.Identity.Web is 2.15.2.

We are developing a SPA with Razor Pages and using Microsoft.Identity.Web for Azure AD authentication in this SPA.

We have been collecting Trace logs and Exception logs when AADSTS54005 occurs, and here are a part of those logs.

The error AADSTS54005 occurs after accessing https://login.microsoftonline.com:443/{Application_ID}/oauth2/v2.0/token from the internal process of /signin-oidc during the sign-in process.

For more details, please see the attached image file 'EndToEndTransactionDetails.png'.

EndToEndTransactionDetails

As shown in the timeline of the image file, there are two accesses to /oauth2/v2.0/token within /signin-oidc, and the response code of the second access is Bad Request (400).

It seems that AADSTS54005 is occurring because a new token could not be obtained due to the second access to /oauth2/v2.0/token returning a response code of 400, and the token obtained from the first access to /oauth2/v2.0/token is reused.

For more details, please see the attached file 'logs.csv'.

logs.csv

Up to line 35 is the log of the first successful call to /oauth2/v2.0/token. From line 36 onwards is the log of the second call to /oauth2/v2.0/token that returned a Bad Request.

What kind of request would cause a Bad Request (400) to /oauth2/v2.0/token is a matter of great interest, but in our environment, capturing the access from /sigin-oidc to /oauth2/v2.0/token is not allowed, so we cannot know.

However, in situations where AADSTS54005 occurs, /signin-oidc also returns a Bad Request (400), and we have captured the request from the web browser to /signin-oidc at that time.

The attached file 'BadRequestLog.txt' is the captured request when /signin-oidc returned a Bad Request (400). (Just to note, the timing of the logs in 'logs.csv' and the occurrence of 'BadRequestLog.txt' are different.)

BadRequestLog.txt

As you can see from the file, there are lots of .AspNetCore.OpenIdConnect.Nonce. and .AspNetCore.Correlation. in the value of the Cookie header.

At the time of occurrence of AADSTS54005, it is confirmed that the request header to /signin-oidc is similar to the request header in 'BadRequestLog.txt'.

In IIS, it is known that a response of Bad Request (400) happens when the size of the request header exceeds the limit.

In fact, in our environment, it seems that the request header is limited to about 16KB, but the size of the request header saved in 'BadRequestLog.txt' exceeds 16KB.

Therefore, it is presumed that when accessing /oauth2/v2.0/token from /signin-oidc results in a Bad Request (400), the request's Cookie header also contains numerous .AspNetCore.OpenIdConnect.Nonce. and .AspNetCore.Correlation..

If you have any other information that might help solve the problem, please let us know. We will share as much as we can.

ahiraiwa commented 10 months ago

@TejendraPrasad

I am getting the same error "AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token." after updating Version to 2.15.2.0.. It was fine for 1 month....

Was there anything unusual that happened in that 1 month? For example, did the site recycle due to an application deployment or a scheduled recycle?

In our environment, we are implementing Azure AD authentication for SPA using Microsoft.Identity.Web.

We have found that if a recycle occurs every 29 hours during peak times when many users are using this SPA, AADSTS54005 occurs when users try to sign in after the recycle.

TejendraPrasad commented 10 months ago

@ahiraiwa , For me, the issue is not with IIS scheduled recycling because it didn't happen before; instead, IIS restarted in order to make the system working again.

ahiraiwa commented 9 months ago

@TejendraPrasad Thank you for your reply.

Looking at the error message in this post, it appears that the exception is occurring at the same location as I reported.

Specifically the following part

09:53:35] [Error] [Microsoft.Identity.Web.TokenAcquisition] False MSAL 4.56.0.0 MSAL.NetCore .NET 6.0.15 Microsoft Windows 10.0.17763 [2023-11-17 09:53:35Z - 77da2591-ddf7-40c0-adf6-c6ccf4c43238] Exception type: >Microsoft.Identity.Client.MsalUiRequiredException , ErrorCode: invalid_grant HTTP StatusCode 400 CorrelationId 77da2591-ddf7-40c0-adf6-c6ccf4c43238

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, Func2 onBeforePostRequestData) at Microsoft.Identity.Client.OAuth2.OAuth2Client.GetTokenAsync(Uri endPoint, RequestContext requestContext, Boolean addCommonHeaders, Func2 onBeforePostRequestHandler) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.ConfidentialAuthCodeRequest.ExecuteAsync(CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)

This is the same Exception log I reported here, line 46 of log.csv.

In our environment, site recycling is definitely one of the causes of AADSTS54005.

According to my log, it is the request to https://login.microsoftonline.com:443/{Application_ID}/oauth2/v2.0/token that is causing AADSTS54005.

This request after recycle of web application site causes a Bad Request (400) because this request is not appropriate for IIS for some reason.

We also know that the cookie header of /signin-oidc is bloated, resulting in a Bad Request (400), so it is likely that https://login.microsoftonline.com:443/{Application_ID}/oauth2/v2.0/token may also have a large request header size for some reason.

So I am thinking that capturing that request using Fiddler when AADSTS54005 occurs may provide a clue to solving the problem.

TejendraPrasad commented 9 months ago

@ahiraiwa , thank you!

IIS recycle is regular on daily basis on our server so it might be second one large header size...but as per @jmprieur he has fixed the issue in 2.15.1 and it was working fine until i updated to 2.15.2.

https://github.com/AzureAD/microsoft-identity-web/pull/2489

AndreErb commented 9 months ago

@ahiraiwa The bloated cookies is just a follow-up error, which can occur, when already being in the "AADSTS54005: OAuth2 Authorization code was already redeemed"-Problem. The problem is causing a loop of Challenge/Loging-Retries which all fail, adding a huge amount of "Correlation"-Cookies. I already mentioned it here
However, it's NOT the source of the problem itself.

About the "IIS recycle": I don't think that this is the root cause for the problem, too. But it increases the chance for encountering the problem. The same is true, when the IIS-process is shutdown (sleeping) due to inactivity. In both cases, the initialization code of ASP.NET Core / Web.Identity is re-run, when the app starts again, after being called by users.

I strongly believe, it's still a race condition bug in the Identity lib, which somehow still subscribes to the Token-events, which leads to multiple/parallel calls to the Azure endpoints, using the same Authorization Code and therefore failing as "already redeemed". Restarting (or receycling) the app, can solve the problem (for some time) as it may clear the "multiple event subscriptions".

The only thing, which worked for us, was using this Workaround. However, this clearly can't be the solution and makes it even worse, as it hides the real problem.

@jmprieur Any news on this? Are you still working on this, as it is still a huge problem?

nromano32 commented 9 months ago

It is possible that these are related.

https://github.com/AzureAD/microsoft-identity-web/issues/2612

TejendraPrasad commented 7 months ago

@nromano32, will latest Microsoft.Indentity.Web and .NET 8 solved the issue?

Any Code change?

As i use below code

services.AddMicrosoftIdentityWebAppAuthentication(Configuration) .EnableTokenAcquisitionToCallDownstreamApi() .AddInMemoryTokenCaches();

nromano32 commented 7 months ago

It did ... no code changes other then described

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(options => { Configuration.Bind("AzureAd", options); options.Events.OnTokenValidated = HandleOnTokenValidated; options.Events.OnAuthenticationFailed = HandleOnAuthenticationFailed; options.Events.OnRedirectToIdentityProviderForSignOut = HandleOnRedirectToIdentityProviderForSignOut; options.Events.OnRedirectToIdentityProvider = HandleOnRedirectToIdentityProvider; }) .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) .AddMicrosoftGraph(Configuration.GetSection("AzureAd")) .AddDistributedTokenCaches();

Issue https://github.com/AzureAD/microsoft-identity-web/issues/1995 points to a races condition that was fixed in .net 8.0 and ported to .net 7.0 but not patched in .net 6.0. For me this made sense in that my handlers were firing multiple times in a single call in Staging.

We have had no problems since the upgrade. Hope it fixes your issue!

Best - Nick

nromano32 commented 7 months ago

https://github.com/AzureAD/microsoft-identity-web/issues/1995#issuecomment-1358457234

josh-shaw-dev commented 6 months ago

@jmprieur We are still seeing the same issue, not that often but still is appearing

We are not using Blazor however, using net 6 with mvc razor pages

Tried updating to "Microsoft.Identity.Web" Version="2.16.0" last time this happened though we have seen it again since.

Happens on deploy so application startup and the only way to fix it delete the deployment and re deploy (we are on Service Fabric)

Seems the same traces as @ahiraiwa in app insights Screenshot 2024-02-27 140810

Going to try the hack in 1995-comment and see if that will resolve it.

josh-shaw-dev commented 6 months ago

I can reliably reproduce it with our codebase though I am struggling to break that down into a minimal repro I can pass on as it acts as expected when used in a minimal mvc app

@ahiraiwa Are you using SignalR in your mvc app? The blazor users will be though wondering if this is a common theme here

Anyone else on Service Fabric?

My findings so far...

When starting up I can hold a breakpoint in our configuration of the MicrosoftIdentityOptions till what seems the signalr connections timeout then after that time it will trigger the error already redeemed token

After resuming on this breakpoint i'll see Hub 'NotificationHub' is now disconnected from '(Primary)https://sigr-redacted.service.signalr.net(hub=NotificationHub)'. Please check log for detailed info. Connection d8aa1aa1-8e41-431a-9699-c8076ec31c1d received error message from service: Connection ping timeout.

image

This configure options in MicrosoftIdentityWebAppAuthenticationBuilderExtensions will be called multiple times when the failure case happens image

jennyf19 commented 3 weeks ago

And everyone is seeing this on 3.0.x as well?

TejendraPrasadPatel commented 3 weeks ago

@jennyf19, we just updated to latest and performing testing before go live.. keep you updated if its resolved.. as per other post .net8 and latest version has resolved the issues.