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.
Related
I have a problem when trying to introduce Spring Security to my webapp. Here's my web.xml:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:application-context.xml
classpath:web-context.xml
classpath:security-context.xml
</param-value>
</context-param>
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/admin</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<session-config>
<session-timeout>30</session-timeout>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
<!-- Spring Security config -->
<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>
security-context.xml:
<security:http auto-config='true'>
<security:intercept-url pattern="/admin.html" />
<security:http-basic />
</security:http>
<security:http pattern="/services/**" security="none" />
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="admin" password="analyzer4321"
authorities="ROLE_ADMIN" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
When I'm trying to run server I have this exception on start:
java.lang.IllegalArgumentException: A universal match pattern ('/**')
is defined before other patterns in the filter chain, causing them to be ignored.
Please check the ordering in your <security:http> namespace or
FilterChainProxy bean configuration.
I have no idea what I'm doing wrong. Any suggestions?
This section in your security-context.xml file:
<security:http auto-config='true'>
<security:intercept-url pattern="/admin.html" />
<security:http-basic />
</security:http>
is processed before this (the second) one (because of their order):
<security:http pattern="/services/**" security="none" />
The first section says: restrict access to /admin.html and allow free access to any other page.
The second section is useless. It says: allow access to all pages that match /services/**. But this has already been allowed by the first section.
You can remove the second section, or put it before the first.
See the Spring Security Reference for more details on using multiple <http> tags.
BTW, <intercept-url> tag usually has an access attribute. I am not sure whether <intercept-url> can be used without access. See here for details.
The first pattern Spring security takes up is from the http tag in the pattern attribute. If no pattern attribute is declared in the http tag, it defaults to <security:http pattern="/**">
the intercept-url tag attribute is allways taken up in second place ie after de http pattern tag.
If you have two or more http tags, you should allways declare the pattern attribute with values so no conflicts occur
I am trying to secure my RESTful API using Spring 3.2.4 and Spring Security 3.2 using the #Secured annotations. I have the following setup:
web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:spring/*.xml
/WEB-INF/classes/security/security-context.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring Security -->
<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 configuration -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/servlet/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>
servlet-context.xml:
<context:component-scan base-package="com.mycompany.rest.controller" />
<security:global-method-security secured-annotations="enabled" />
security-context.xml
<beans:bean id="merchantUserDetailsService" class="com.mycompany.rest.security.CustomUserDetailsService" />
<http auto-config="false" create-session="never">
<http-basic />
</http>
<authentication-manager>
<authentication-provider user-service-ref="customUserDetailsService" />
</authentication-manager>
I am programmatically assigning custom roles (ROLE_GROUP, ROLE_DIVISION, ROLE_READ, ROLE_WRITE) in the customUserDetailsService to the user and this works fine.
One of my controllers:
#Secured("ROLE_DIVISION")
#RequestMapping(method = RequestMethod.GET)
ResponseEntity<List<CustomerResource>> getCustomer() throws ResourceDoestNotExistException {
List<Customer> providers = // retrieve providers from DAO
List<CustomerResource> resources = customerResourceAssembler.toResources(customers);
return new ResponseEntity<>(resources, HttpStatus.OK);
}
Now to my problem, the #Secured annotations are being ignored. I want to use the #Secured annotation to avoid having to define multiple 's in the configuration. Spring Security works fine when I add at least one , but how can avoid defining them and instead rely on the #Secured annotations?
I can now access the method above with an user with the role "ROLE_GROUP".
Looks like you have everything right except that you've enabled the wrong type of annotations. If you check the documentation for global-method-security you'll see there's a separate attribute called secured-annotations which enables #Secured.
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>
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
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.