Get principal user object in service methods - spring

In my spring MVC application i want to access Principal object created by spring security in my service layer. I thought about injecting it in my service classes, but I am sure it will not be thread safe.
Other option I am thinking, is to pass it to all service methods as argument but this do not look very clean to me.
What would be the better way to do this?

I think that the best approach would be to use the SecurityContextHolder.
Principal principal = SecurityContextHolder.getContext().getAuthentication();
Spring explains how it works in the documentation:
The most fundamental object is SecurityContextHolder. This is where we
store details of the present security context of the application,
which includes details of the principal currently using the
application. By default the SecurityContextHolder uses a ThreadLocal
to store these details, which means that the security context is
always available to methods in the same thread of execution, even if
the security context is not explicitly passed around as an argument to
those methods. Using a ThreadLocal in this way is quite safe if care
is taken to clear the thread after the present principal's request is
processed. Of course, Spring Security takes care of this for you
automatically so there is no need to worry about it.
Since it uses a ThreadLocal to store the current authentication, you will not have any thread safety problem.

Related

How does filters interact with authentication providers in Spring Security?

If I understand correctly, the AuthenticationProvider authenticate Authentication that they support, but how does the Authentication object gets created in the first place?
Is it the filter's responsibility to initialize them?
At what point are they passed into the providers?
See JavaDoc:
In most cases, the framework transparently takes care of managing the security context and authentication objects for you.
Authentication is a Spring managed bean. It´s initializated by the Spring framework and passed to the Authentication provider by default when the context is created.

Spring Security - Method level security and non-authenticated invocations

I have a vanilla Spring Boot application that consists of a controller, a service and a DAO layer. The controller code calls the service code and so on.
To implement some semblance of security, I am currently using Spring Security 4.0.x's global method security annotations in combination with Spring Security ACL to lock down my service methods.
Requests that go through my controllers are auth-ed and authorized just fine because a principal / user is in context. HOWEVER, I also have some additional non-user facing code that listens for messages from an AWS queue. Within this listener code I invoke some secured services (to stay DRY and not duplicate business logic) but for this situation no user is in scope.
Generally speaking:
For a situation like the one I'm describing, what is a good / acceptable way to authenticate user-less method invocations e.g. ones that don't come through an HTTP request (or to bypass the check)? I am considering manually setting the SecurityContextHolder with a "system user" in my message listener code but this has some code smell.
Is method level security better applied at the controller level?

Best practice for accessing Spring's Security Context

I am working on a application with a layered architecture:
Presentation - Service - Data Access
Many of the modules at this service layer need access the currently logged in user. Is it a good idea to have these modules directly access the security context to obtain the UserDetails object?
I'm thinking that if in the future modules from the Service layer need to be exposed to other application as a Web Services, getting the Security Context may not work.
You'd need to be more specific, but you generally shouldn't have the whole stack directly accessing authentication information. Instead, if it's an operation where using aspect-oriented method security isn't applicable, pass the user information to service layers as ordinary method parameters. Use appropriate mechanisms (such as #AuthenticationPrincipal) to cleanly supply authentication information to your top-level facade (Web tier or what have you).

Spring security context, several users

I don't understand one thing. If for example 5 users are logging into your application so spring security creates 5 different context ? I'm little confused about contexts in spring.
All components in spring are Singleton (by default). So if I create one component and two different authenticated users are working on this component so they are working on the same data ?
SecurityContext is kept in SecurityContextHolder with thread local strategy by default. Which means that SecurityContext will be scoped to a thread.
In Spring MVC application each request runs in its own thread. And Spring Security (SecurityContextPersistenceFilter in particular) populates the SecurityContextHolder with SecurityContext found in the HTTP Session (if one already exist).
So if five users are logged in your application, five security contexts will exist but only the one belonging to the user making the request will be available from the thread handling the request.
And for the second part of your question, yes, multiple users will be working with the same instances of your singleton scoped beans. But I'm not sure that is a problem. Your singleton beans may be services, DAOs, etc. and you probably don't store a state on those which can be directly changed by the users.
Hopefully this brief and simplified post explained it, if not leave a comment and I'll add more details.
More information:
SecurityContextPersistenceFilter JavaDoc

Session Facade in the world of Spring/Hibernate - is it still relevant?

How would we implement a Session Facade design pattern in the Spring application? Would the role of the Session facade be simply served by the service bean class that would be annotated for the transactions and will have a session scope?
A Spring service (with singleton scope) is like a local stateless session bean, it is an implementation of the Session Facade pattern, only for applications that are not distributed. Spring does make the case that in most cases services don't need to be distributed and that the distributed aspects of Session facade are not as all-pervasive as J2EE made them out to be.
(When you say "session scope" it sounds like you're confusing session as in transactional with session as in HttpSession, because Spring uses the term session scope to refer to HttpSessions. (At least it's confusing me about what's intended.) My reading of the Session facade description leads me to think it doesn't have anything to do with an HttpSession.)
Anyway, I'd say the basic goal of encapsulating complexity is still valid. In some cases the goal of giving distributed access is still very valid, it's just not the default case like J2EE tried to make it out to be. And Seam makes a case for stateful session beans still being relevant.
Session should be associated with the web tier, not services.
Services do indeed own transactions, so they should have that annotation.

Resources