Spring Boot session expires during POST request - java

I have a Spring Boot/Spring Security application made via Java 16 and Spring Boot v2.7.5 and running on embedded Tomcat server.
The strange thing about it that I've indicated session timeout to 4 hours using application.properties (can be found below), but when I do POST request after e.g. 3.5 hours of inactivity the session expires despite this setting and redirects me to login screen. Moreover, I've done several checks to investigate this issue and I've figured out that if I do a GET request instead then the session remains and then I can do any request I want without timeout.
Could you advise what can trigger such behaviour, please?
My first thoughts were about cookies and/or CSRF token lifetime. However, looks like CSRF token has no expiration time and it remains the same all the time the session exists. The same thing is about JSESSIONID cookie behavior by default. However, I also tried to set server.servlet.session.cookie.max-age property to 4 hours and it didn't work neither.
Please note, that if I set session timeout to quite lower values like default 30 minutes, everything works as intended. Also, I've checked session timeout internaly after server is running using RestController and calling HttpServletRequest.getSession().getMaxInactiveInterval() and the returning value was always equal to server.servlet.session.timeout value, so looks like nothing overrides this property or something.
Thank you for the answers in advance!
Please take a look at my application.properties document below:
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://uri;databaseName=DBName
spring.datasource.username=user
spring.datasource.password=pwd
spring.datasource.hikari.connectionTimeout=400000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=false
server.servlet.session.timeout=240m
server.error.whitelabel.enabled=true
server.error.include-message=never
server.error.include-binding-errors=never
logging.file.path=./log/
spring.web.resources.cache.cachecontrol.no-store=true
spring.web.resources.cache.cachecontrol.must-revalidate=true
spring.mail.host=smtp.com
spring.mail.properties.mail.smtp.ssl.trust=smtp.com
spring.mail.port=587
spring.mail.username=user#email.com
spring.mail.password=pwd
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
server.port=443
server.ssl.key-store-type=PKCS12
server.ssl.key-store=keystore.p12
server.ssl.key-store-password=pwd
server.ssl.key-alias=tomcat

Related

Spring Boot/Auth0 - How do I specify the connection?

I am working on setting up an application using Spring Boot and Auth0. We are refactoring from a legacy codebase to use Spring Boot. In the legacy code, the Auth0 URL is created manually by appending the URL parameters:
https://[removed].auth0.com/authorize?
response_type=code
&client_id=[removed]
&scope=openid email profile
&connection=[removed]
&state=[removed]
&redirect_uri=http://localhost:8081/login/oauth2/code/auth0
With the Spring Boot configuration (guide here: https://auth0.com/docs/quickstart/webapp/java-spring-boot/01-login), this is the URL that generates:
https://[removed].auth0.com/authorize?
response_type=code
&client_id=[removed]
&scope=openid email profile
&state=[removed]
&redirect_uri=http://localhost:8081/login/oauth2/code/auth0
The Spring Boot URL is giving me an error "[invalid_request] no connections enabled for the client".
I am missing the "connection" parameter with the Spring Boot setup. I have tested by manually copying the URL and adding the "connection" parameter and I get the login page. Without it, I get the error.
On Spring's configuration page (https://docs.spring.io/spring-security/reference/servlet/oauth2/login/core.html#oauth2login-boot-property-mappings), I don't see an option for Connection. I didn't see anything on the SecurityFilterChain that would allow me to change this either.
I see that Auth0.js has a function that allows a "connection" parameter (https://auth0.com/docs/libraries/auth0js). How do I add this using Spring Boot/Java?
EDIT
application.properties:
spring.security.oauth2.client.registration.auth0.client-id=[removed]
spring.security.oauth2.client.registration.auth0.client-secret=[removed]
spring.security.oauth2.client.registration.auth0.scope[0]=openid
spring.security.oauth2.client.registration.auth0.scope[1]=email
spring.security.oauth2.client.registration.auth0.scope[2]=profile
spring.security.oauth2.client.provider.auth0.issuer-uri=[removed]
EDIT 2
We were working in conjunction with Auth0 Support - they provided us the following information:
In case an Enterprise connection is the only enabled connection for an
application and the "connection" parameter is not specified on the
/authorize request, you need to enable the "show as a button" setting
on that enterprise connection, otherwise you will get "no connections
enabled for the client" error.
The "Display connection as a button" checkbox is on the "Login
Experience" tab of the connection setting page.
Weird configuration requirement - you can't go directly to the login page. You have to have a button to take you there. This did resolve the original issue; however, I marked #Codo answer below as accepted, as it did answer this question and appears it would work from initial testing.
You are looking for a way to add an additional parameter to the authorization URI. It's isn't as straightforward as one would like but doable.
Fortunately, it's described in Customizing Authorization and Token Requests with Spring Security 5.1 Client.
You probably want to implement the steps 2 and 4:
Add your own implementation of OAuth2AuthorizationRequestResolver, override both resolve() methods to call customizeAuthorizationRequest()
Implement customizeAuthorizationRequest() to add the additional connection parameter (OAuth2AuthorizationRequest already support additional parameters)
Implement a security configuration class to register CustomAuthorizationRequestResolver as the authorization request resolver
Several issues on GitHub ask for a simpler way. But the issues are still open (or closed as duplicates).
Update
Instead of clientRegistrationRepository() (at the end of step 2), you could declare clientRegistrationRepository as an injected dependency and the use it without parentheses:
#Autowired
private ClientRegistrationRepository clientRegistrationRepository;
Spring Security comes with with mostly preconfigured Auth0 module. Unless you're doing something specific, there's no need to construct URL yourself.
Have you done Spring configuration as said in the link you've posted: https://auth0.com/docs/quickstart/webapp/java-spring-boot/01-login#configure-spring-security ?
# src/main/resources/application.yml
spring:
security:
oauth2:
client:
registration:
auth0:
...
Here's another option (untested):
In application.properties, specify all URLs separately. So instead of:
spring.security.oauth2.client.provider.auth0.issuer-uri=xyz.us.auth0.com
Specify:
spring.security.oauth2.client.provider.auth0.authorization-uri=https://xyz.us.auth0.com/authorize?connection=azuread
spring.security.oauth2.client.provider.auth0.token-uri=https://xyz.us.auth0.com/oauth/token
spring.security.oauth2.client.provider.auth0.jwk-set-uri=https://xyz.us.auth0.com/=.well-known/jwks.json
spring.security.oauth2.client.provider.auth0.user-info-uri=https://xyz.us.auth0.com/userinfo
Note that the authorization URI already includes the connection parameters. All the other parameters should then be appended.
You can get all the URIs at https://xyz.us.auth0.com/.well-known/openid-configuration (just replace "xyz" and put the URL in your browser).

increase swagger requestTimeout

is there anyway that can help me increase the timeout of the swagger request that i issue to my RestAPI using " Try it out" of swagger ?
i roamed the internet and disn't find something usefull, and i tried to add things to my yml conf files, but i didn't know what to write
i expected to find something like this maybe :
swagger.timeout=5000
i have a spring boot application using swagger in order to test my webservices in a restController. i have a treatement that takes about 30 seconds, the thing that makes swagger throw a 500 timeout error for me.
thanks !
As far as I know, Swagger registers its endpoints as normal Spring controllers so use the underlying web container to serve its traffic.
Try to increase the global connection timeout:
server.connection-timeout=120000
Time that connectors wait for another HTTP request before closing the connection. When not set, the connector's container-specific default is used. Use a value of -1 to indicate no (that is, an infinite) timeout.
solved by adding this to ZUUL's (API Gateway)
ribbon:
ReadTimeout: 120000
ConnectTimeout: 120000

Spring Boot not loading username from application.properties

I'm developing a simple web application with spring boot. In the first step, I implemented everything about the page itself and a simple login. Additionally, I implemented a database access using mysql and hibernate. My database runs on a local easyphp devserver.
In the first step, everything worked fine. However, after a reset of the database and recreating the user with the same credentials, Hibernate is not able to get a connection:
2018-02-09 21:17:11.487 ERROR 9592 --- [ restartedMain] o.a.tomcat.jdbc.pool.ConnectionPool : Unable to create initial connections of pool.
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Access denied for user ''#'localhost' to database 'db'
As I can understand, no username was configured. But in my application.properties, a username is set:
spring.datasource.url=jdbc:mysql://localhost:3306/db?userSSL=false
spring.datasource.username=user
spring.datasource.password=
The exception occurres on startup, so it has to be the configuration. At the database, the user 'user' has all priviliges at the database 'db', but no one on others.
The data source URL might be causing the issue. Is that a typo? Can you check by resetting it to the following? It has to be "useSSL" instead of "userSSL"
spring.datasource.url=jdbc:mysql://localhost:3306/db?useSSL=false
spring.datasource.username=user
spring.datasource.password=
If the above does not work, your problem might be related to permissions for the user. A question posted here relates to yours (although it is in PHP).
Hopefully this resolves it, let us know.
Ok, found the solution by myself. The real username contained a '_' like 'user_name'. Somehow this character was the problem why the username was not read.
Edit: Worked a few times, but the problem still exists...

Strange behaviour of Tomcat 8.0.32: sometimes it ignores cookies. Can it be somehow debugged?

There is a very weird problem with our Tomcat 8.0.32 installed under Ubuntu 16.x.
This problem starts to happen accidentally and exists until tomcat server restart (so it is reproducible after it begins happen).
What happens, is that some of the requests send by timer from JS application with proper cookie: JSESSIONID= value are improperly processed: the Tomcat can not find Session object for it (from Spring MVC layer it means, that user is not authenticated). All requests with the same JSESSIONID being sent before this broken request, and all requests being send after (again with the same value of session id) - they all work fine!
We also certainly see that all headers in that request are correct (they are printed out by our application in some Filter), but Session object is not restored.
So basically it sounds like under some circumstances the Tomcat starts ignoring JSESSIONID from the requests sent via redirect from another server. And again, this does not happen always, only after some time of web-application life.
I will not provide any code here or configuration settings. First, because it looks like the poor Tomcat problem, second, because configuration is standard (out of the box after apt-install).
My question is: how can we configure the Tomcat in order to log all operations related to the JSESSIONID processing? Like that it finds session for the given ID, or does not and so on.
UPD: This never happens with more newer version of Tomcat 8.5.5. But due to some reasons it can not be updated on that particular server. My current goal is to collect evidences about this behaviour to be sure that it is a bug, or some strange default configuration that tomcat installation.
According to the docs https://tomcat.apache.org/tomcat-8.0-doc/logging.html
to enable debug logging for part of Tomcat's internals, you should configure both the appropriate logger(s) and the appropriate handler(s) to use the FINEST or ALL level. e.g.:
org.apache.catalina.session.level=ALL
java.util.logging.ConsoleHandler.level=ALL

User session closed after 20 minutes

I have configured a 20 minute session timeout in the web.xml file of my war. But I am calling my servlet to keep the session active after 20 minutes using this JavaScript code:
setInterval(function () {
$.get("sessionKeepAlive");
}, 240000);
Everything is working fine in the Dev environment, but in QA it's not working. We are using a load-balancer in QA. I want to know if there is anything that we can change in the server configuration cse to get around this issue.
web.xml:
<session-config>
<session-timeout>10</session-timeout>
</session-config>
Ok there can be a number of things to look at:
Since you are using a Load Balancer, it suggests you are using multiple Java servers (app servers or servlet containers) - you should ensure your Session sharing (clustering) mechanism is properly configured. Also, your back-end server may require you to add the <distributable /> tag to your web.xml. (The downside of this approach is that sharing sessions across more than a handful of back-end servers is not really advisable, unless absolutely necessary)
An alternative option to using clustering/session sharing, as mentioned by #piet.t is to ensure that Session stickiness is enabled on your load balancer - this would ensure that requests using the same session always go back to the same server. (The downside of this approach is that you risk losing a lot of sessions if 1 server dies)
As #JB Nizet suggested in the comments above, you should ensure your AJAX GET request is not being returned from the browser cache - this is sometimes done by adding a random number to each GET request (eg. The time in milliseconds)
Thanks all for your reply :)
I just checked and found that the session stickiness time on the load-balancer is 3 minutes. This means the load-balancer can send the request to any server after 3 minutes even if the session is active.
For time being I have changed the js method, and later I will update the session active time on the load-balancer.
setInterval(function () {
$.get("sessionKeepAlive");
}, 240000);

Categories

Resources