response.sendRedirect() in Spring vs JSF - spring

All,
I've hit a roadblock implementing OpenId due to some unexpected behavior storing session information.
The basic outline is as follows
// In OpenId Initialize Servlet
request.getSession().setAttribute("isLinkingRequired", true);
response.sendRedirect(openIdUrl);
// In Open ID Verify Servlet
boolean linkCheck = request.getSession().getAttribute("isLinkingRequired") != null
The sample provided to me by Intuit is written with Spring. In the Spring app, linkCheck evaluates to true. The previously stored session information is there.
My app is written with JSF (in particular, Oracle's ADF framework). In my case linkCheck evaluates to false. All previous stored session attributes are gone!
This has caused me a boatload of problems. Can anyone explain this odd behaviour?

Related

What can cause a LazyInitatializationException whereas Spring Open In View is enabled?

I am analysing a "classic" Hibernate error :
org.hibernate.LazyInitializationException : could not initialize proxy – no Session.
I am wondering how it could happen whereas the Spring Open In View mode is enabled?
If you have any documentation or knowledge on a possible reason, please share.
Thanks
Here are some feebacks on my context, and an example of what could cause LazyInitializationException event if Spring Open In View is enabled.
Context
My application is a REST API server developed with Spring Boot 2.5.3.
Spring Open In View is kept enabled by default.
A lot of Services are annotated with #Transactional methods.
Spring-data is used, and Entitymanager too, to create some native queries.
The error
One REST API request, that generates a lot requests to the database (both selections and insertions), fails with LazyInitializationException.
Debugging
By setting a breakpoint when LazyInitializationException is thrown, I discovered that the exception is thrown in org.hibernate.proxy.AbstractLazyInitializer#initialize, because the session is null. Then I discovered that the session is set to null, when the method EntityManager.clear is called. For any reason I don't know, this method was explicitely called in the code.
Fixing
So I just removed the call to EntityManager.clear, and the request works. I'm still wondering why previous developers wanted to clear the EntityManager, probably because they were confused with the transaction management.
Conclusion
Even in Spring Open In View is enabled, and as a result, event if a Hibernate Session is opened, calling EntityManager.clear unset the session to the entities loaded before. Then trying to access a Lazy Loaded field on those entities throws LazyInitializationException.
I hope this will help someone.
Here is the documentation from the latest hibernate version.
As you can see
Indicates an attempt to access not-yet-fetched data outside of a
session context. For example, when an uninitialized proxy or
collection is accessed after the session was closed.
Most probably somewhere you read some entity and then outside of a transaction you try to read some collection which was by default lazy loaded. So then another request needs to be done to database, but since you are out of transaction you receive this exception.
This usually occurs in case you load an entity without the annotation #Transactional or some other configuration to load it inside a transaction and then you give this to your controller to be returned to the user. Then the controller will use jackson or some other library to convert the entity object into a json and will try to read any field. At this point trying to read any lazy loaded collections from the entity, will result in this exception since the read will be outside of a transaction.

Spring Boot 2.3.4: Bug with JwtValidators.createDefaultWithIssuer(String)?

I found an odd behavior with JWT parsing and JwtValidators.
Scenario:
Spring Boot OIDC client (for now a tiny web app, only displaying logged in user and some OIDC objects provided by Spring)
Custom JwtDecoderFacotry<ClientRegistration> for ID-Token validation
JwtValidatorFactory based on JwtValidators.createDefaultWithIssuer(String)
This worked well with Spring Boot version <= 2.2.10.
Debugging:
NimbusJwtDecoder (JAR spring-security-oauth2-jose) uses claim set converters. The 'iss' (issuer) claim is handled as URL.
JwtIssuerValidator (internally created by JwtValidators.createDefaultWithIssuer(String)) wraps a JwtClaimValidator<String>.
this one finally calls equals() that is always false - it compares String with URL.
My current workaround is not calling JwtValidators.createDefaultWithIssuer() but just using the validators new JwtTimestampValidator() and an own implementation of OAuth2TokenValidator<Jwt> (with wrapping JwtClaimValidator<URL>).
Anyone else having trouble with this?
--Christian
It's a bug. Pull Request is created.

Spring Security 4 sessionRegistry doesn't populate Principal list

I am trying to implement a function where a admin user can terminate another user's session. I followed the official Spring Security documentation here: http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#list-authenticated-principals and started with getting all currently logged in users through sessionRegistry.getAllPrincipals(), but it always returned an empty list.
I set a breakpoint in SessionRegistryImpl.registerNewSession() and could see it did indeed get invoked and it did add the UserDetails (my own implementation with both equals() and hashCode() implemented) to the hashmap principals. But when I access sessionRegistry bean from a Spring MVC controller, the list is always empty.
My configuration looks pretty much the same as the documentation.
How to fix this? Did anyone successfully get SessionRegistry to work with Spring Security 4? I remember I made it work with Spring Security 3 by following these intructions(enter link description here)
OK, so I fixed the issue by cleaning up the Spring configuration files, as suggested by the comments. Someone messed up with the web.xml - he added a reference to the context XML that is already referenced by the Spring's DispatcherServlet, causing it to be loaded twice. He didn't know it, because Spring references the file implicitly.
P.S.
I learned my lessons, but 2 things the Spring folks could do better (maybe in Spring 5?):
There shouldn't be implicit context file loading. Currently, the framework will try to load the application context from a file named [servlet-name]-servlet.xml located in the application's WebContent/WEB-INF directory. Convention over configuration fails in this case.
There should be warning when a bean is loaded twice, if someone need to override a bean definition, he must declare explicitly. Otherwise it would take a lot of time to debug the kind of error this mistake will cause.

Struts 2 tomcat request/session contamination

I am using Struts 2 v 2.3.16.3 with tomcat 6.
A user will click on an action which finds an object by id and the page displays it. I have encountered a sporadic bug where the user will all of a sudden get the id of another lookup from another user on another machine. So effectively they are both calling the same action but passing different id to the request, but both end up viewing the same id.
This is obviously disastrous, and the data is totally corrupted as both users think they are editing a different record. Any ideas how make sure session/request activity is kept secure to each session?
I am also using spring and am using the #Transactional annotation in my Service layer, which returns the objects from the DAO. Is there something I need to do with this annotation to make it secure for each session ?
I am using org.springframework.orm.hibernate3.HibernateTransactionManager
Classic Thread-UnSafe problem.
Since you nominated Spring, my first guess is that you have not specified the right scope for your action beans in Spring xml configuration.
Be sure you are using scope="prototype" because otherwise the default scope of Spring is Singleton, and you don't want a single(ton) instance of an Action, that would not be ThreadLocal (and hence ThreadSafe) anymore.
If it is not that, it could be something on an Interceptor (that, differently from an action, is not Thread Safe), or you are using something static (in your Business / DAO layer, or in the Action itself) that should be not.

spring-security-redirect is not read by spring security 3.1?

So we're using spring-security-redirect as a parameter in the form that is sent to j_spring_security_check, in order to send the user to the correct page after a successful login. Migrating from Spring security 3.0 to 3.1, this stopped working. We use a subclass of SavedRequestAwareAuthenticationSuccessHandler, overriding onAuthenticationSuccess(), and debugging that method I see that getTargetUrlParameter() returns null. isAlwaysUseDefaultTargetUrl() returns false.
Browsing around I can't find anyone having similar problems... I find some references to AbstractAuthenticationTargetUrlRequestHandler.DEFAULT_TARGET_PARAMETER, which seems to have disappeared in 3.1.
Any ideas?
As per Spring security 3.1 xsd,
Attribute : authentication-success-handler-ref
Reference to an AuthenticationSuccessHandler bean which should be used to handle a successful authentication
request. Should not be used in combination with default-target-url (or always-use-default-target-url) as the
implementation should always deal with navigation to the subsequent destination.
So, in your subclass, you have to perform the redirection.

Resources