Session functionality in application layer? - spring

I'd like my application layer to be aware of which user is logged in to simplify method signatures - for instance method(owner, object) would be simply method(object). I use Spring Security for security though I'd like to keep Spring out of my application layer so there is a separate layer just for that purpose (and DTO conversion) - like a facade (adapter for application services).
How to make the application layer aware of the user context its operating on without using spring?

You would need to register a Filter or HandlerInterceptor that would have a look at the HttpSession and, if the user is logged in, store some kind of User representation in some static ThreadLocal context. Any class could then have access to this static ThreadLocal containing your User object.
You would have to remove this object when the user logs out or session expires. Hint: HttpSessionListener.

Related

How to properly provide Authentication object (SecurityContext) to application itself?

Most of my application is secured with method level security (AspectJ, but it doesn't matter) and now that I am trying to call some code from within application itself (not controllers, but e.g. EventListener) I can't help to wonder if Spring Security provides some out-of-box way of giving Authentication object to the application itself, otherwise I cannot get past my method security since application has null security objects (Authentication in SecurityContext, if it even exists - depends on situation, You might have to init it first).
Sure I can do something like this (just before running relevant code):
UserDetails ud = User.builder()
.username("APPLICATION")
.password("APPLICATION")
.roles("APPLICATION")
.build();
Authentication auth = new UsernamePasswordAuthenticationToken(ud, ud.getPassword(), ud.getAuthorities());
SecurityContextHolder.getContext()
.setAuthentication(auth);
But is it safe to do this in deployment (security-wise)?
Is there any guarantee on which thread will own this SecurityContext? What about other threads and their tasks?
Once set, can it stay there? Will it for the rest of app's run (can be days/months), context could be reloaded, etc. I lack deep Spring knowledge to know what happens Thread-wise inside Spring.

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 - JEE tag with user-service-ref attribute loses mapped roles

I'm pretty new to spring, let along spring security, and I've been looking at the Schema files and noticed a <jee> tag that appears under the <http> tag which acts like some sort of preauth filter magic. Using the mappable-roles attribute, I can get the role that I want but, when I specify a different user-service-ref attribute, specifying a UserDetailsService object, I lose the role.
My guess is because when I specify the UserDetailsService object, Spring assumes I don't need the role anymore... but I do!
Any ideas on this? Can I capture those details somehow? If not with this simple <jee> tag, what does the jee tag expand to for custom-filters and pre-auth, etc?
The <jee> tag creates (among others) a PreAuthenticatedAuthenticationProvider bean which delegates to a configured strategy for loading user details.
The default implementation of this strategy is PreAuthenticatedGrantedAuthoritiesUserDetailsService which will simply copy the roles it finds in the authentication token.
By overriding this default strategy with your custom UserDetailsService using the user-service-ref attribute you take the responsibility for assigning roles to the user. If you want to keep the default behavior regarding user roles, you can simply copy the related line from the above mentioned class, as the Java EE roles are still mapped, and are accessible in the auth token to your own code as well.

Using a Stateful Session Bean to track an user's session

it's my first question here and I hope that I'm doing it right.
I need to work on a Java EE project, so, before starting, I'm trying to do something simple and see if I can do that.
I'm stuck with Stateful Session Beans.
Here's the question :
How can I use a SFSB to track an user's session?
All the examples that I saw, ended up in "putting" the SFSB into a HttpSession attribute.
But I don't understand why!
I mean, if the bean is STATEFUL, why do I have to use the HttpSession to keep it?
Isn't an EJB Container's task to return the right SFSB to the client?
I've tried with a simple counter bean.
Without using the session, two different browsers have the same counter bean (clicking on "increment" changed the value for both of them).
Using session, I have two different values, each for every browser (clicking on "increment" on Firefox, added one just to Firefox's bean).
But my teacher told that a SFSB keeps the "conversational state with a client", so why it doesn't just work without using a HttpSession ?
If I understood correctly , isn't using HttpSession with a SFSB the same of doing it with a SLSB instead?
I hope that my question(s) is clear and that my English is not that poor!
EDIT :
I'm working on a login system.
Everything goes fine and after completing the login it takes me to a profile page that show user's data.
But reloading the page makes my data disappear!
I've tried adding HttpSession while logging but doing in this way makes the data stay even after the logout!
A Stateful Session Bean (SFSB) has to be combined with the HTTP session in a web environment, since it's a pure business bean that itself knows nothing about the web layer.
Traditionally EJBs even mandatory lived inside their own module (the EJB module), that couldn't even access web artifacts if they wanted to. This is an aspect of layered systems. See Packaging EJB in JavaEE 6 WAR vs EAR for more information about that.
The original clients for Stateful Session Beans were among others Swing desktop applications, that communicated with the remote EJB server via a binary protocol. A Swing application would obtain a connection to a remote Stateful Session Bean via a proxy/stub object. Embedded in this proxy is an ID of some kind that the server can associate with a specific SFSB. By holding on to this proxy object, the Swing client can make repeated calls to it and those will go to the same bean instance. This will thus create a session between the client and the server.
In the case of a web application, when a browser makes an initial request to a Java EE web application it gets a JSESSIONID that the server can associate with a specific HTTPSession instance. By holding on to this JSESSIONID, the browser can provide it with each followup request and this will activate the same http session server-side.
So, those concepts are very similar, but they do not automatically map to each other.
The browser only gets the JSESSIONID and has no knowledge about any SFSB ID. Unlike the Swing application, the browser communicates with web pages, not directly with Java beans.
For mapping the client's request to a specific stateful session bean, the EJB container only cares about the ID provided via the SFSB proxy. It can't see if the call happened to originate from code in the web module and can't/shouldn't really access any HTTP contexts.
The web layer being the client code that accesses the SFSB must 'hold on' to a specific proxy reference. Holding on to something in the web layer typically means storing it in the HTTP session.
There is however a bridge technology called CDI that can make this automatic connection. If you annotate your SFSB with CDI's #SessionScoped and obtain a reference to the SFSB via CDI (e.g. using #Inject), you don't have to manually put your SFSB into the http session. However, behind the scenes CDI will do exactly that anyway.
You need to define the bean with #SessionScoped instead of #RequestScoped (if you are looking for HttpSession equivalent solution)
something like
#SessionScoped
public class SessionInfo implements Serializable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Have a look at following (explained in detail)
http://www.oracle.com/technetwork/articles/java/cdi-javaee-bien-225152.html

Access to User ID in Spring

I'm doing some proof-of-concept work with Spring MVC and security. So far I've managed to write a simple web-app which has a secure webpage which requires a user to login and have the correct role before accessing the database and listing some data. I'm using Spring 2.0.8 by the way.
What I require is that, after the user has logged on, is to access the user principal object for the current session to pass into my DAO layer. I'd like to do this through the standard bean wiring, so it will have to be something determined at runtime.
Any pointers to get started ?
Cheers
Neil
SecurityContextHolder#getContext() will return a SecurityContext associated with the current user request.
From there, you can call getAuthentication().getPrincipal() to get the data associated with the logged-in user.
There is no need to inject any bean, the static method in SecurityContextHolder will take care of accessing the correct thread-local data.

Resources