The requirements for our custom filter are the following:
- You can only have one instance of a page
- If you create a new tab and enter the same page, you will not be able to access the page again and you will be redirected to a custom page
- If you create a new browser, same result
- If you create close and open the same browser, same result
- If you refresh the same tab, same result
- You can only gain access if you manually log-out
- You can only gain access if you clear your browser's cache
- You can only gain access if your session has expired
If you need to learn more about the FilterChainProxy and ordering of the aliases, please check the Spring Security Reference Table 2.1. Standard Filter Aliases and Ordering
The format for adding the filter is similar to the following:
Before we start adding real code, let's declare a pseudocode first:
if user has logged-in for the first time flag the session that the user has logged-in if the user tries to log-in again check if there's a protected URL if yes, redirect user to a custom page if no, then proceed with the remaining filtersAnd here's the actual implementation for this filter.
SingleEntryFilter
This filter extends OncePerRequestFilter and overrides the doFilterInternal() method
What is OncePerRequestFilter?
Filter base class that guarantees to be just executed once per request, on any servlet container. It provides a doFilterInternal(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.FilterChain) method with HttpServletRequest and HttpServletResponse arguments.How did we came up with this implementation? I'm sure it didn't just came out from thin air. Actually, I had to study how the CONCURRENT_SESSION_FILTER alias is implemented. It's filter class is based on ConcurrentSessionFilter.
The getAlreadyFilteredAttributeName() method determines how to identify that a request is already filtered. The default implementation is based on the configured name of the concrete filter instance.
Source: Spring Reference 3 for OncePerRequestFilter
What is ConcurrentSessionFilter?
Filter required by concurrent session handling package.Let's examine the doFilter() method of this class.
This filter performs two functions. First, it calls SessionRegistry.refreshLastRequest(String) for each request so that registered sessions always have a correct "last update" date/time. Second, it retrieves a SessionInformation from the SessionRegistry for each request and checks if the session has been marked as expired. If it has been marked as expired, the configured logout handlers will be called (as happens with LogoutFilter), typically to invalidate the session. A redirect to the expiredURL specified will be performed, and the session invalidation will cause an HttpSessionDestroyedEvent to be published via the HttpSessionEventPublisher registered in web.xml.
Source: Spring Security 3 Reference for ConcurrentSessionFilter
ConcurrentSessionFilter
This ConcurrentSessionFilter does the following steps:
1. Retrieve the current session
2. Check if session is not null
3. Check if the SessionInformation is not null
4. Check if the session has expired. If expired, logout and redirect
5. If not expired, continue with remaining filters.
Let's compare this with our custom filter SingleEntryFilter.
Inside the doFilterInternal() method, we do the following:
1. Retrieve the current session and verify if it's not null
2. Retrieve the SessionInformation and verify if it's not null
3. Retrieve the session attribute hasLoggedIn and check if it's null or not
If hasLoggedIn is not null, this means the user has logged already.
4. Next, we loop the guardURI list and check if there's a protected URL. If there's one, we redirect to the redirectURI
5. If this is the user's first time to access the site (i.e new session), set the hasLoggedIn attribute
6. Finally, continue with the remaining filters
Examine how this code resembles the ConcurrentSessionFilter
Now, let's update the the Spring Security XML configuration.
spring-security.xml
The changes we did in this file is we added the following custom filter:
We also declared the singleEntryFilter bean.
Notice the guardURI is a list. That means we can protect multiple URIs. Cool :)
We then need to update our login controller so that we can see the invalid login alert.
LoginLogoutController
To access the site, please login first by entering the following URL:
http://localhost:8080/spring-security-single-login-filter/krams/auth/loginThen access the following URL:
http://localhost:8080/spring-security-single-login-filter/krams/main/commonYou can only access the URL once! Here's what you'll get if you try again:
That's it. We've just finished implementing our custom filter based on the requirements we laid earlier. They key action here is we studied the existing filters to see how Spring Security does things. I believe this is a good way to enhance one's knowledge of this framework.
Please read the tutorial Spring Security 3 - MVC: Querying the SessionRegistry for a complete step-by-step guide for the other parts of this application.
The best way to learn further is to try the actual application.
Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring3-security-mvc-integration-tutorial/
You can download the project as a Maven build. Look for the spring-security-single-login-filter.zip in the Download sections.
You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run
Share the joy:
|
Subscribe by reader Subscribe by email Share
great!
ReplyDeletethanks men.
@swing.magic, you're welcome :)
ReplyDeleteFirst thing first, love the tutorials they've been helping me out like crazy. Now here is the issue I'm having upon logging on as john with the pass admin I'm getting a null pointer exception on like 53 of SingleEntryFilter.java. I tried everything I could think of to fix the issue but it's still happening. Figured I'd ask to see if you could find where I'm screwing up. Thanks.
ReplyDeleteHi Krams i want to implement Jasper batch export feature using Spring Jasper.Is Spring Jasper Providing this feature i have done some r&d and got the below url
ReplyDeletehttps://jira.springsource.org/browse/SPR-1207
As this suggests that there no batch export feature in spring jasper.
Am i correct???
Plz help
Hey,
ReplyDeleteAs explained in this post, i am not getting expected result
Firstly i accessed the url which is http://localhost:8080/spring-security-single-login-filter/krams/auth/login
after that i accessed the url http://localhost:8080/spring-security-single-login-filter/krams/main/common
but i was expecting i should get redirected to http://localhost:8080/spring-security-single-login-filter/krams/auth/login-alert page
but it is not...
and one more point here is, after successful login using the url
http://localhost:8080/spring-security-single-login-filter/krams/main/common
if i refresh the page i am getting redirected to
http://localhost:8080/spring-security-single-login-filter/krams/auth/login-alert
which is wrong redirection... I am not login again where i just refreshed the page...
The above code needs to be improved in such a way that it should not redirected to alert page if refresh is happened.
I want to add this solution to JSF Spring Security based web application, where I need to have only enable one user to be able to login to one browser, even if a user tries to see login page after loggedIn he/she should be redirected to authenticated page for the current user. Can u show me an example for this scenario
ReplyDeleteThe programs dont work as explained the tutorial
ReplyDeleteI have read your blog its very attractive and impressive. I like it your blog.
ReplyDeleteSpring online training Spring online training Spring Hibernate online training Spring Hibernate online training Java online training
spring training in chennai spring hibernate training in chennai
Hello!! I'am glad to read the whole content of this blog and am very excited.Thank you.
ReplyDeletegclub casino
gclub
gclub casino
Finding the time and actual effort to create a superb article like this is great thing. I’ll learn many new stuff right here! Good luck for the next post buddy..
ReplyDeleteBest Industrial Training in Noida
Best Industrial Training in Noida
Really it was an awesome article...very interesting to read..You have provided an nice article....Thanks for sharing.
ReplyDeleteBest BCA Colleges in Noida
yurtdışı kargo
ReplyDeleteresimli magnet
instagram takipçi satın al
yurtdışı kargo
sms onay
dijital kartvizit
dijital kartvizit
https://nobetci-eczane.org/
İKR7T
golden goose
ReplyDeletesupreme hoodie
curry shoes
kyrie 8 shoes
fear of god outlet
jordan shoes
curry shoes
jordan travis scott
off white hoodie
golden goose