Identity server 4 - GetToken slowness intermittently - performance

We have implemented Identity server 4 for our API suite and we have a SLA of 6 secs for the clients that consume our service.
What we have observed is first request of the day to generate the token for all the clients takes around 6-7 seconds, subsequent request takes 100-200ms.
We are unable to pinpoint the setting that is contributing to this, as we do not reset AppPool/IIS.
Any help here would be appreciated.
PS: We fetch clients from DB and all the token settings are being set here.

Ok here is an update on the issue for the token generation code that is being used as below:
var disco = await client.GetDiscoveryDocumentAsync(new
DiscoveryDocumentRequest()
{
Address = configuration.GetSection(IdentityServer).Value,
Policy = { RequireHttps = false }
});
as we are using JWT calling of CreateDiscoveryDocument is not necessary and the identity server URL can be passed directly. Changing this saved couple of seconds.
However, I am still wondering why this happens for every client any thoughts?

Related

Erroneous token validations with reCAPTCHA v3

Our team is developing a simple Angular website that sends a form data to our backend via API. This website will be published under a public IP, so the interaction will be protected with Google reCAPTCHA v3.
Recently we decided to run some stress tests in a pre-productive environment in order to see if everything is stable and works correctly. So we set up a simple JMeter tests group with 100 users and 100 loops. This way we had 10000 requests in total to our API. So, having all that configured, we ran the frontend in order to generate a reCAPTCHA token, executed the action which sends the data to the API and copied the generated token into the JMeter configuration.
The API, before passing the form data to the backend, checks if the token is valid by making a request to “https://www.google.com/recaptcha/api/siteverify”, specifying this token and the secret key generated in the reCAPTCHA admin console.
After executing the JMeter tests, we saw that a certain amount of requests bypass the validation of the token and end up in the backend, while the token has already been used.
What we tried?
Stress test of our API with 10k requests in order to try the validation of an already used reCAPTCHA token.
What we expected to happen?
All the requests to return an error code of 401, beacause the reCAPTCHA token has already been used before and those tokens are single use only (the 401 code is returned by our API if the request to "/siteverify" returns a "success:false" in the response body or a status code other than 200).
What actually resulted?
5% of the requests bypassed the validation and ended up in the backend.
JMeter results
(The 400 bad request errors are returned by the backend, after the validation of the token has already been done, meaning that the token was assumingly valid)
We chequed the logs of our API and we've been able to verify that, in fact, the "/siteverify" requests return a status code of 200 and a response body of "success:true" in those 5% of the tests.
To me, it seems like some kind of balancing problem, maybe some node didn’t have enough time to replicate the status of that token? Or maybe the problem comes from our implementation… Hopefully someone could give us a hint!

Jersey/Jetty API Handler/Container resends the GET request every 1 min if it does not receive the response within 1 minute

<jersey.version>2.23.2</jersey.version>
<jetty.version>9.4.11.v20180605</jetty.version>
There is a GET API resource registered with Jersey and I am hitting this API from Postman. In case, the num of records is less and can be fetched within 1 minute, API works fine. But, if the request takes more than 1 minute to process, the Jetty Container closes the previous request Socket and retries by sending same GET request to same API again(no external requests are sent, Jetty is retrying them itself).
FYI : There is no SSL Session being used here.
These are non-Async requests.
Q 1. Any idea why Jetty does that ?
Also, I tried to change the timeouts in ServerFactory like so, but nothing changed the above behaviour :
((DefaultServerFactory)startupConfig.getServerFactory()).setIdleThreadTimeout(Duration.minutes(4));
startupConfig.getMetricsFactory().setFrequency(Duration.minutes(4));
Q 2. Any idea what settings need to be changed ?
On Production, SSL Sessions are being used and I don't see this problem there.
Q 3. How would SSL Session change this behaviour of resending the new API requests bu Jetty ?

OAuth Access token expired while uploading large file to the server

I have web application where I am uploading the large file more than 1 GB from browser to the server. Depending on network speed some time it will take more than 1 hour.
Server endpoint is secured with OAuth.
When upload request is sent from browser it has valid token with 1 hour expiry.
In case of large file upload, it gives Unauthorised error because of token expiry after 1 hour.
How can I solve this problem where token should validate only in the beginning of the request not after complete file upload?
Technology used
AngularJs - UI
SpringBoot version 2 - Backend
POST request
Content-Type: Multipart/form-data
I dont have option to increase the token expiry beyond 1 hour.
The reason is that the tomcat will receive the file firstly, then dispatch the servlet request to your controller. When the upload takes too long time and the token has already expired, the security check will return 401, and your request will never enter the controller (the security check is before your controller).
You can put a breakpoint in your controller with the MultiPartFile parameter, then try to upload a huge size file to verify what I said.
One possible solution is you resolve the servlet yourself, maybe something like:
uploadFile(HttpServletRequest rawRequest)
Then when a token already expired, you can refresh it rather than return 401 then discard the already uploaded file.
Hope this may help you, and if you have a better idea, please let us know. Thank you!
useful link: https://docs.spring.io/spring-framework/docs/5.3.x/reference/html/web.html#mvc-multipart

AWS API Gateway returns 200 with response but later returns 200 with no response

I am running into an issue with an API Gateway/Lambda implementation. I've written a authentication service that works across subdomains and appears to work fine in most cases. Testing locally works perfect.
When it is deployed to AWS, with the API in a Lambda with an API Gateway in front of it, the log in system works great. The user can login, which returns a 200 and then a ReturnClaims-style endpoint returns their access, and other useful account bits.
The problem arises that after a little while (like an hour or so usually) the ReturnClaims endpoint will continue to return a 200 but the response is now empty when the page is refreshed.
The HTTP-Only cookie still lives in the browser and it's not throwing any errors.
When running locally, this issue doesn't arise at all. The user can refresh for as long as the cookie has and JWT has been instructed to last (which is 30 days but I've adjusted this for testing purposes as needed).
I am hoping someone might have an idea of what might cause an endpoint on AWS to function in this manner, perhaps some life setting I am unaware of?
I appreciate any advice or suggestions. Thanks!

Intermittent Http Error 403 When Invoking Google Custom Search API

I'm getting the following error intermittently when invoking the custom search api from a server side setup:
HttpError 403 when requesting https://www.googleapis.com/customsearch/v1?q=John+Doe+john%40simpler.com&alt=json&cx=&key= returned "There is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your API key configuration if request from this IP or referer should be allowed.
I'm using a server api key, and have confirmed that the configured server ip address is correct. And about 50% of the time my request come back fine, too. I'm issuing the request from the server like this:
service = build("customsearch", "v1",
developerKey=api_key)
custom_search_context = <my_context>
res = service.cse().list(
q=search_query_string,
cx=custom_search_context,
).execute()
My requests per sec are well with in the configured limit of 10/sec and daily purchased limit of 5000 requests.
One more thing I noticed is that Google counts a forbidden request towards the daily limit, too.
Any pointers on why I'm being presented with the error only intermittently would be very helpful
The error can be raised when you're exceeding a request/second limit. Can you confirm that your request rate is below your configured user rate limit? It might be worth noting that the limit is enforced even if you don't explicitly provide a user value in your requests.

Resources