spring & WelcomeController - spring

after connected, I would like to force to forward on the action in WelcomeController
because i need get some information from user connected (Principal) and put them in session
the problem that i have is: if user try to connect by any url accessible, after connected (user+pass OK), spring re-forward automatic to this url
here is my web.xml
<servlet>
<servlet-name>xyz</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/xyz-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>xyz</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>1440</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
how could i do this?
thanks a lot
best regards

What you want to do, it is done straightaway with spring-security.
Just integrate spring security, block access to the entire content, but leave the login page accessible to all. When a user access a secure url, the application will show the login page.
This is an example of mapping in security.xml
<http>
<intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/**" access="ROLE_PERSON"/>
<form-login login-page="/login" default-target-url="/dashboard"/>
<logout invalidate-session="true"/>
</http>

Related

Allow Specific URL patterns to bypass Spring Security Login

I have a web application protected by spring security. However, there is one particular URL pattern that I do not want to apply any security to. I've tried a few different approaches, but none of them seem to be working. Whenever I attempt to go to that specific URL, I am forwarded to the spring_security_login page.
A piece of the web.xml:
<!-- NOT SECURE -->
<servlet>
<servlet-name>dontSecureServlet</servlet-name>
<servlet-class>org.com.gov.lol.DontSecure</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dontSecureServlet</servlet-name>
<url-pattern>/dontSecure</url-pattern>
</servlet-mapping>
<!-- SECURE -->
<servlet>
<servlet-name>secureServlet</servlet-name>
<servlet-class>org.com.gov.lol.Secure</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>secureServlet</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<!-- SECURITY FILTER -->
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
A piece of the security-context.xml:
<!-- This did not work -->
<http pattern="/dontSecure" security="none" />
<http entry-point-ref="entryPoint" use-expressions="true">
<custom-filter ref="customFilter" position="PRE_AUTH_FILTER" />
<!-- I've also tried adding the following here (with no luck) -->
<intercept-url pattern="/dontSecure" filters="none" />
<intercept-url pattern="/secureMe" requires-channel="https" />
<intercept-url pattern="/secureUs" requires-channel="https" />
</http>
<!-- I have even tried adding a separate <http> block just for /dontSecure -->
<http>
<intercept-url pattern="/dontSecure" security="none" />
</http>
Again, with any combination of the above configuration, the url /dontSecure is still forwarded to the spring login page.
Any ideas as to what could be causing this?
Cheers.
UPDATE
From the server logs, it seems that the /dontSecure url is loading the dontSecureServlet. However, an error seems to be generated and I am being forwareded the 404 error page (which is configured as /404.htm, which must be what brings me back to the login page).
I've included some extra snippits from the web.xml that I didn't think were relevant at first.
Try to change your intercept-url in your configuration with this one:
<intercept-url pattern="/dontSecure/**" access="permitAll" />
not in a separate <http> tag
The problem might be caused by the fact that your custom filter is getting applied to all the paths. You have to find a way to register your custom filter only for certain paths (I could show you how to do this in Spring Boot, but you probably aren't using it).

Static HTML files issue in spring 3

I all,
i have a spring application working with role based security. Application is working fine it's just i need to introduce some static HTML pages which will also be hosted in the same war. So if www.myapp.com/abc/work.jsp is my secure page then www.myapp.com/home.htm should show static html page. I have incorporated HTML files but issue is i am getting 404 on www.myapp.com/home.htm and www.myapp.com/abc/work.jsp works fine.
web.xml -
<display-name>guru</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-security-config.xml</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/home.htm</welcome-file>
</welcome-file-list>
My app-security-config.xml
<http auto-config="false" disable-url-rewriting="false" access-decision-manager-ref="accessDecisionManager"
entry-point-ref="authenticationProcessingFilterEntryPoint">
<custom-filter position="FORM_LOGIN_FILTER" ref="authenticationProcessingFilter" />
<custom-filter position="LOGOUT_FILTER" ref="customLogoutFilter"/>
<access-denied-handler error-page="/login.jsp?login_error=true"/>
<intercept-url pattern="/login.htm" filters="none" />
<intercept-url pattern="/abc/def/**" access="ROLE_USER"/>
<intercept-url pattern="/**" access="ROLE_ANONYMOUS" />
<anonymous enabled='true'/>
<session-management session-authentication-strategy-ref="sas"/>
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
</http>
Hi you should provide a mapping for static contents inside your dispatcher servlet configuration, something like:
<mvc:resources mapping="/resources/**" location="/WEB-INF/" />
In this way, if your static home.htm content is located inside /WEB-INF/ folder you can reach it from the url /resources/home.htm.
This will avoid that spring intercept and redirect to a controller all paths starting with /resources reserving that path to static resources like images, css files, scripts and html static pages

Spring Security Session Timeout - Clear Browser Cache

I currently have a web application that is utilizing Spring Security hosted on a JBoss 5 server.
My issue is that if a user is idle for a few minutes then their session times out due to web.xml setting. Once in a while they when try to hit the webapp when their session is invalid they get a 404 error. The only way the browser can see the web app is when the user clears their browser cache.
Is there a way a fix for this so that the user doesn't have to clear out their browser cache?
Here is my spring security xml
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/login" access="permitAll" />
<security:intercept-url pattern="/resources/**" access="permitAll" />
<security:intercept-url pattern="/import/trades" access="permitAll" />
<!--
The roles are prefix with the word ROLE
and it is upper case due to ldapAuthoritiesPopulator config section
-->
<security:intercept-url pattern="/**" access="hasAnyRole('ROLE_NBFIEPN_USERS', 'ROLE_NBFIEPN_DEVELOPERS')" />
<security:form-login login-page="/login" authentication-failure-url="/login?error=true"/>
<security:logout />
</security:http>
Here's my web.xml file. I have currently set the session timeout to 1 minute to replicate the issue.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>TBA Web Application</display-name>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/security-config.xml
</param-value>
</context-param>
<servlet>
<servlet-name>horizon</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/applicationContext.xml
/WEB-INF/spring/applicationContext-service.xml
/WEB-INF/spring/mvc-config.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>horizon</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Session Timeout in minutes -->
<session-config>
<session-timeout>1</session-timeout>
</session-config>
</web-app>
Add this configuration to your spring security configuration
<security:http...>
...
<security:session-management invalid-session-url="/login"/>
</security:http>
Desription for invalid-session-url parameter:
The URL to which a user will be redirected if they submit an invalid session indentifier. Typically used to detect session timeouts.
It should guid the user with an invalid session to the login page.

Spring MVC, Spring Security and Hibernate cannot autowire properties between contexts

I am using Spring MVC 3.0.6 and Spring security 3.0.7. I cannot #Autowire the RoleDao class to my user class when in the security context.
my web.xml file:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/security-app-context.xml
</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The security-app-context.xml:
<beans:bean id="chineseCheckersEntryPoint" class="com.nike.golf.security.ChineseCheckersAuthenticationEntryPoint" />
<beans:bean id="chineseCheckersFilter" class="com.nike.golf.security.ChineseCheckersAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
</beans:bean>
<http use-expressions="true" auto-config="false" entry-point-ref="chineseCheckersEntryPoint">
<intercept-url pattern="/secure/extreme/**" access="hasRole('supervisor')" />
<intercept-url pattern="/user/**" access="permitAll" />
<intercept-url pattern="/profile/**" access="isAuthenticated()" />
<intercept-url pattern="/secure/**" access="isAuthenticated()" />
<custom-filter position="PRE_AUTH_FILTER" ref="chineseCheckersFilter" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="chineseCheckersAuthenticationProvider" />
</authentication-manager>
<beans:bean id="chineseCheckersAuthenticationProvider" class="com.nike.golf.security.ChineseCheckersAuthenticationProvider" />
In my user object where it uses the roleDao, it's null. It has not been autowired. From all the research I have done online it seems to be related to the different contexts, and not being able to autowire between them.
Can someone help me understand these contexts and how I can get them into the same context?
Thank you everyone for your help. I managed to figure this out.
This question was similar to mine and got me moving in the right direction:
Declaring Spring Bean in Parent Context vs Child Context
This forum post really simplified the idea for me.
In your web.xml file you define the servlet context and the application context.
The application context is configured through these pieces of XML:
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/security-app-context.xml
</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
any number of *context.xml files you pass into the context-param > contextConfigLocation are in the application context. This is the parent context.
The servlet context gets created in the web.xml file by this bit of xml:
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
The servlet context as the child context has access to the application context (parent).
This was the key thing for me to understand. So I moved all configuration I had in the servlet context, up to the application context.
Like the answer in the other question I linked to above says #Autowired still does not work. Anyone know the reason for that?
So to get around this I defined the beans and the properties in the xml all the way from the property I was concerned with down to the sessionFactory.
The thing is now I could wire up the beans I needed in xml all the way up the hierarchy to sessionFactory because it was in the same context, since I moved it up to the application context from the servlet context where it was before.
In my question I didn't even post the servlet-context.xml file because I didn't think it needed to be touched, but in fact I needed to move the configuration up to the app context if I wanted to wire things up to my security beans.
I hope that makes sense.
You can imagine a context as a set of Spring beans.
Contexts can be nested, so that the outer context can access the beans from the inner one, but not the other way around. An example for this are typical web application, the have two contexts: the inner one specified with the contextConfigLocation and loaded by ContextLoaderListener, and the outer one configured with the DispatcherServlet.
One way to merge two xml files to one context, is introducing a third apllication configuration xml file, that only include then other xml files via bean:include. And then you have only to specify this third xml files for the loader. But I am not sure if you really have 2 application contexts configured for ContextLoaderListener. -- Anyway you can try the trick with the 3. xml file.

Spring security issue with 404 error?

greetings all, i am using spring security 3.0.2, urlRewrite 3.1.0
, and i have a problem with spring security that i have a rule that all the pages in the app requires authentication except for some pages so my security.xml is:
<http use-expressions="true" >
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/error" filter="none" />
<intercept-url pattern="/**" access="isAuthenticated()" />
.
.
.</http>
in the web.xml i have defined the error page
<error-page>
<error-code>404</error-code>
<location>/p/error</location>
</error-page>
and the issue is that if i am not a logged in user, and typed some url that doesn't exist in the app like app/notFoundUrl the spring security matched this page to the pattern /** which requires authentication, so the user is not redirected to the error page as expected, but redirected to the login page and after it, redirected to the error page
and i want that if the user typed a bad url if he's logged in or not, he's redirected to the error page directly.
i think that the problem is related to the web.xml, here's it:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- Beans in these files will makeup the configuration of the root web application context -->
<!-- Bootstraps the root web application context before servlet initialization-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Deploys the 'projects' dispatcher servlet whose configuration resides in /WEB-INF/servlet-config.xml-->
<servlet>
<servlet-name>p</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/servlet-config.xml
</param-value>
</init-param>
</servlet>
<!-- Maps all /p URLs to the 'p' servlet -->
<servlet-mapping>
<servlet-name>p</servlet-name>
<url-pattern>/p/*</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/p/error</location>
</error-page>
<!-- force encoding on the requests -->
<filter>
<filter-name>encoding-filter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding-filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Security -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/application-config.xml
/WEB-INF/app-security.xml
/WEB-INF/mvc-config.xml
</param-value>
</context-param>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
</web-app>
any ideas how to solve this issue ?
You have said:
i want that if the user typed a bad url if he's logged in or not, he's redirected to the error page directly
Spring security will intercept every request before it knows whether its url is valid or not, so a way to get it would be intercept all valid urls with some patterns, and add at the end a general pattern which could be accessed by anyone.
<intercept-url pattern="/" access="permitAll" />
<intercept-url pattern="/validUrl1Pattern" access="permitAll" />
<intercept-url pattern="/validUrl2Pattern" access="permitAll" />
<intercept-url pattern="/validUrl2Pattern" access="permitAll" />
...
<intercept-url pattern="/**" access="ROLE_ANONYMOUS" />
The problem of this configuration is that is probably difficult to find patterns for all the valid urls if your application is complex.
Yep just add this:
<intercept-url pattern="/error/**" access="permitAll" />
That will make it so that anyone can get to all your error pages.
when you set the attribute access="true", you tell spring-security to check if the user has the security attribute (which is normally a role) named "true" . I don't think that is your goal?
to bypass security, you may set filters="none" and skip the access attribute:
<intercept-url pattern="/errorpage" filters="none" />
see documentation of <intercept-url>
Add /error to your list of <intercept-url/> elements so that it doesn't require authentication in order to access it.

Resources