I'm developing application in Spring Boot and I need jwt authentication there. I decide to use that github project, but when I'm looking at code I don't understand sense of SecurityContextHolder.
Here are 2 classes which are using it:
AuthenticationRestController.java
JwtAuthenticationTokenFilter.java
Can you tell me what is purpose of SecurityContextHolder? I want stateless authentication without session. So I just need generate jwt and next check it before requests.
This git project also has disable session:
...
httpSeccurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
...
I've tried delete code with SecurityContextHolder and applicatin still works fine.
Thanks for answers.
Here is a quote from Learning Spring 5.0:
One major aspect of security is storing the information of the principal currently used by the application. It is held by the security context of the application. SecurityContextHolder is the most important object of the framework as it stores the details about security context in ThreadLocal. It means the security context will be available to the methods that are executed in the same thread. However, in a few circumstances, all the threads in the application may need to use other strategies for using the security context. The framework provides two ways to change the default nature of using ThreadLocal. The developers can either set the system property or they can invoke the static method on SecurityContextHolder.
The reason your application still works after deleting code with SecurityContextHolder is that by using the SessionCreationPolicy.STATELESS creation policy you request Spring Security to not create an HTTP session and not store logged in user’s SecurityContext in the session.
When to use SessionCreationPolicy.STATELESS
to stop creating sessions during the entire lifespan of the application
to stop using sessions during the entire lifespan of the application
Related
I am a newbie in Spring, so I am explaining my requirement.
My requirement is to create an web - application in spring, where sign in / log in should be from 1 system. If user gets logged in , in another browser/system the previous should be out of session.
How can I achieve this ? Any document link or any concept that I need to learn will be helpful.
You can use spring-session-redis - it's an API with implementation for managing a user’s session information with Redis.
Application uses command line to execute GET request on same server running on different ports, to explain how the session works. You can build POST, DELETE and other HTTP request.
HttpServletRequest and HttpServletResponse interfaces are implemented by the web-container wrapping your application.
If you are using Spring boot it uses embedded Tomcat instance, if you are deploying your WAR application on Weblogic, they are implemented by Weblogic.
However, the interfaces are the same and depending on your configuration on those containers, they maintain Session objects.
Using this session object, you can add key-value pairs and maintain same set coming from the same user in consequent requests.
#RequestMapping(value = "/hello")
public Object hello(HttpServletRequest request, HttpServletResponse response){request.getSession().setAttribute("key",mySessionObject);}
when you want to retrieve the session object you have just added, just use getAttribute() method with same key.
request.getSession().getAttribute("key")
We are migrating our application from SpringSecurity 3 to 4. We have our ConcurrentSessionControlStrategy bean configured to always create session (Grails notation to define beans)
sessionRegistry(SessionRegistryImpl)
sessionAuthenticationStrategy(ConcurrentSessionControlStrategy, sessionRegistry) {
alwaysCreateSession = true
}
because we are using HTTP requests with basic authentication from Excel and other apps to interact with application and without that option, session is not created and authentication has to be done for every action instead of once for first action.
In Spring Security 4 ConcurrentSessionControlStrategy was migrated to ConcurrentSessionControlStrategy (according to migration guide - http://docs.spring.io/spring-security/site/migrate/current/3-to-4/html5/migrate-3-to-4-xml.html ) which should be used inside of CompositeSessionAuthenticationStrategy but we cannot find a way to setup session strategy.
The workaround we currently have is to call non-basic authenticated page before authentication, what causes session to be created and following requests will be executed against this session
Comment from M. Deinum pointed me into another direction and I have found that in spring-security-core plugin of Grails securityContextPersistenceFilter is defined with forceEagerSessionCreation = false. Overriding this bean to force eager session creation did the trick
securityContextPersistenceFilter(SecurityContextPersistenceFilter, ref('securityContextRepository')) {
forceEagerSessionCreation = true
}
This probably can also be done using configuration of Grails Spring Security Core
Source code is available here:
https://github.com/grails-plugins/grails-spring-security-core/blob/master/src/main/groovy/grails/plugin/springsecurity/SpringSecurityCoreGrailsPlugin.groovy
I am using spring security #PreAuthorise to check who and who cannot access methods in my service layer. It works really well. Usually my service methods are annotated with
#PreAuthorize("hasAnyRole('MY_USER_ROLE')")
My problem is that I have a war file made up of several jar files. Each of these jar files is responsible for a segment of business logic. I now want one of the services in one jar file to access another service in another jar file. This gets rejected because of the permissions. If I comment out the permission then everything works.
Is there anyway I can authenticate via spring before calling this service? (Perhaps with a dummy user?) Or perhaps turn off the security for jars within the same application? Or is my design wrong?
Anyone else has this sort of problem? What design should I use instead?
You need to give the thread that invokes the service (in the other jar) the permissions that are required by #PreAuthorize (for the invoked service).
If the thread is triggered in an web application by an user request, then this are normally the users permissions.
But if the thread is triggered by some timer service then you need to give them the right authentication
Authentication authentication = new UsernamePasswordAuthenticationToken("dummy", "password");
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(authentication);
I believe this is a good example where you should use Spring security #Secured annotation
What is #Secured annotation?
From version 2.0 onwards Spring Security has improved support substantially for adding security to your service layer methods. It
provides support for JSR-250 annotation security as well as the
framework's original #Secured annotation.
Source: Spring Security 3.1 Reference 2.4 Method Security
#Secured annotation allows you to put restrictions in your methods. For example, you can authorize a get() method to be accessible by all
registered users. But for the edit() method, you can mark it be
accessible by admins only.
Check out some tutorials at:
http://burtbeckwith.com/blog/?p=1398
http://krams915.blogspot.in/2010/12/spring-security-3-mvc-using-secured.html
In my web application, there are times when an authenticated admin might want to impersonate another valid user of a system without having to know that user's password.
How can I use Spring Security to give admin users the ability to impersonate normal (non-admin) users of the system?
The Spring Security documentation is silent on this and I can't find anything anywhere. Surely someone must have solved this.
Thanks!
It's in the Spring Security 3 and Spring Security 4 docs aptly named, "Run-As Authentication Replacement."
The AbstractSecurityInterceptor is able to temporarily replace the Authentication object in the SecurityContext and SecurityContextHolder during the secure object callback phase.
I believe the recommended way to do this in Spring Security is with the Domain Access Control lists, see GrantedAuthoritySid #
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/domain-acls.html
However, impersonating another user is more than just having a "delegate identity", you should also consider the implications on logging:
Do you want your logging to appear as Original User or Impersonated User (or both?)
Do you want the "impersonation" to show only what the impersonated user sees, or the superset of permissions of the Original User and Impersonated User?
Yet another possibility is to create a "log in as" feature, which essentially changes the principal identity of the current session - or starts a new session with the impersonated identity.
In all of the above, you may inadvertantly open up a security issue - so I think this is why impersonate-style features are not that common place. Rather, designs trend towards Role Based Access Control (RBAC) or Attribute Based Access Control (ABAC). Using RBAC / ABAC, you could create a delegate style feature where you create delegate attributes/roles - and in the special cases where you need to show the source/target of the delegation (e.g. for audit logs), you handle those as corner cases.
If you want an admin user to be able to impersonate another user (eg for QA/Testing purposes), have a look at the SwitchUserFilter
A decent example of the XML config you need is provided here
I am looking for a security framework for Java web application with Object granularity.
What it means is that I don't just want to filter by urls or by roles, but by specific user ownership of domain objects inside the system.
For example, if there is a Message object that has a Sender user and a Receiver user I would like to be able to configure it so that every Message can be RW by its sender and RO by its receiver.
Or for example, all user profiles are viewable by all users but editable only by the owner.
This rules, of course, I would like to define them with meta data (annotations, xml files, whatever) and not embedded in my business logic.
Is there such a beast out there? Preferably open source.
Spring Security can provide things like method security and "secure objects" using AOP.
You're looking for access control lists (ACLs). Like the other respondents I think Spring Security is worth checking out here--Acegi is just what Spring Security used to be called before they renamed it. Spring Security does have explicit support for ACLs (in addition to URL-based, role-based and group-based access controls). It supports both XML and annotation-based configuration. And you can apply ACL filtering to the view (using taglibs to decide what to render or suppress in the JSP), to methods that return a single domain object (decide whether to allow the method call to succeed), and to methods that return a collection (decide which objects to filter out of the collection before returning it).
You might be able to get away with rolling your own ACL code for simple requirements, but in my opinion ACLs can get tricky pretty quickly. Especially if you have lots of domain objects and you have to start taking performance management seriously.
Check out this link Acegi Security Fundementals - it's slightly outdated but still gives you the main concepts of Spring Security's object level authorization mechanisms.