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

Title: 401 response during Web API Cold Start (issue in JwtOptionsBuilder.cs) #243

Closed
delayed-byte opened this issue Jul 7, 2023 · 1 comment
Labels
bug Something isn't working

Comments

@delayed-byte
Copy link

Describe the bug?

During Cold Start, the JwtOptionsBuilder.cs file encounters a bug where the signingKeyCachingProvider.SigningKeys property is null, leading to a 401 "Authorization has been denied for this request" response. The root cause of this issue is that the signingKeyCachingProvider attempts to use the SigningKeys property before the background thread responsible for retrieving the keys completes its execution.
To mitigate this bug, a solution is needed that ensures the availability of signing keys before they are utilized. One approach is to use the following code snippet to wait until the SigningKeys property of the SigningKeyCachingProvider class is not null before proceeding with execution:

// Wait for background thread to populate SigningKeys
TimeSpan timeout = TimeSpan.FromSeconds(8);
DateTime startTime = DateTime.UtcNow;

while (signingKeyCachingProvider.SigningKeys == null && (DateTime.UtcNow - startTime) < timeout) {
    /*wait*/
}

Another approach involves using a SemaphoreSlim object with an initial count of 0 to coordinate the retrieval of signing keys. When the metadata is refreshed, the background thread can acquire the semaphore, retrieve the signing keys, and release the semaphore. Meanwhile, the main thread can wait on the semaphore until it is signaled by the background thread, indicating that the signing keys are available.

Implementing either of these approaches will ensure that the signing keys are available before they are used, preventing any null reference exceptions or related errors that may occur when the keys are not yet available.

What is expected to happen?

GET call to Web API after cold start should return 200

What is the actual behavior?

Get call to Web API after cold start returns 401 "Authorization has been denied for this request"

Reproduction Steps?

Rebuild and redeploy Web API to IIS.
Call GET method to Web API.

Additional Information?

This is related to
Cache signing keys and update them periodically in order to avoid deadlocks #129

.NET Version

Web API
.NET 4.8

SDK Version

Okta. AspNet 3.2.2

OS version

No response

@delayed-byte delayed-byte added the bug Something isn't working label Jul 7, 2023
@delayed-byte delayed-byte changed the title Title: 401 response during Web API Cold Start in JwtOptionsBuilder.cs Title: 401 response during Web API Cold Start (issue in JwtOptionsBuilder.cs) Jul 8, 2023
@laura-rodriguez
Copy link
Collaborator

laura-rodriguez commented Jul 17, 2023

Hi @delayed-byte,

Thanks for reporting this issue. I'll file an internal ticket to be reviewed and prioritized by the team.
Would you mind sharing any minimal sample project or a Fiddler log?
Also, PRs are welcome; If you feel confident with your proposed solution, feel free to file a PR, and we'll review it.

Thanks!

Internal Ref: OKTA-628591

pixelnix added a commit to pixelnix/okta-aspnet that referenced this issue Dec 11, 2023
Call blocking method RetrieveMetadata() in provider constructor, instead of non-blocking caching method RefreshMetadata(). Ensures that construction of the provider causes a fetch of signing keys on the backchannel, eliminates race conditions that lead to 401 Unauthorized responses on cold start.  Fixes okta#249 and okta#243
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants