A universal match pattern ('/**') is defined before other patterns in the filter chain - spring

I am getting below error while starting tomcat. My application is using Spring security 4.0.2 and Spring 4.2.1
With single spring security file i.e application-security.xml It is working perfectly but when I introduced a new jar which exposed spring-rest feature in same web application then I am getting this error.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChainProxy': Invocation of init method failed; nested exception is 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 namespace or FilterChainProxy bean configuration
I have read may suggestion on stackoverflow.com and other tutorial but could not find the right one to solve my issue.
Here is my application configuration
web.xml
<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/applicationLmc.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<servlet>
<servlet-name>lmc</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>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>lmc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
application-security.xml
<http security="none" pattern="/resources/**" />
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/termsandservice" access="permitAll"></intercept-url>
<intercept-url pattern="/about" access="permitAll"></intercept-url>
<intercept-url pattern="/contact" access="permitAll"></intercept-url>
<intercept-url pattern="/faq" access="permitAll"></intercept-url>
<intercept-url pattern="/jobs" access="permitAll"></intercept-url>
<intercept-url pattern="/terms" access="permitAll"></intercept-url>
<intercept-url pattern="/privacy" access="permitAll"></intercept-url>
<intercept-url pattern="/blog" access="permitAll"></intercept-url>
<intercept-url pattern="/logout" access="permitAll"></intercept-url>
<intercept-url pattern="/login" access="permitAll"></intercept-url>
<intercept-url pattern="/login/signupvalidation" access="permitAll"></intercept-url>
<intercept-url pattern="/signup" access="permitAll" method="POST"></intercept-url>
<intercept-url pattern="/forgotPasswordPage" access="permitAll"></intercept-url>
<intercept-url pattern="/generatePasswd" access="permitAll"></intercept-url>
<intercept-url pattern="/login/resetPassword" access="permitAll"></intercept-url>
<intercept-url pattern="/login/passwordReset" access="permitAll" method="POST"></intercept-url>
<intercept-url pattern="/**" access="hasRole('ROLE_USER')"></intercept-url>
<form-login login-page="/login" authentication-success-handler-ref="lmcAuthSuccessHandler" />
<logout logout-success-url="/login" logout-url="/logout" />
<session-management invalid-session-url="/login">
<concurrency-control max-sessions="2" expired-url="/login" />
</session-management>
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="lmcAuthManager" />
</authentication-manager>
<beans:bean id="lmcAuthManager" class="com.lmc.web.security.auth.LMCAuthManager" />
<beans:bean id="lmcAuthSuccessHandler" class="com.lmc.web.security.auth.LMCAuthenticationSuccessHandler" />
As per multiple suggestion over web, I found that I should defined pattern value in application-security file. But I am not sure what pattern value I need to put because all these needs to be access from web root.
Following is applicationRestService.xml is REST configuration with spring security details
applicationRestService.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="com.lmc.rest" />
<mvc:annotation-driven />
<security:http pattern="/api/**" entry-point-ref="restAuthenticationEntryPoint" use-expressions="true" auto-config="false" create-session="stateless">
<security:custom-filter ref="authenticationTokenProcessingFilter" position="FORM_LOGIN_FILTER" />
<security:intercept-url pattern="/api/**" access="isAuthenticated()" />
<security:logout />
</security:http>
<security:authentication-manager alias="lmcRestAuthManger">
<security:authentication-provider user-service-ref="userDetailsService" />
</security:authentication-manager>
<bean id="userDetailsService" class="com.lmc.rest.security.RestAuthenticationUserDetailService" />
<bean class="com.lmc.rest.security.RestStatelessAuthenticationFilter" id="authenticationTokenProcessingFilter">
<constructor-arg type="java.lang.String">
<value>/api/**</value>
</constructor-arg>
<property name="authenticationManager" ref="lmcRestAuthManger"></property>
</bean>
<bean id="restAuthenticationEntryPoint" class="com.lmc.rest.security.LMCRestAuthenticationEntryPoint"/>
</beans>
Thanks reading it. Any help is appreciated.

Related

Spring Security 4.0.2- Multiple Authentication-manager -Error creating bean with name 'org.springframework.security.filterChainProxy'

We have been working with a single Authentication Manager (LDAP) in spring security for some time, now we require two Authentication Managers one for Login- LDAP and other for IP based security. As IP based security is used as a global filter and LDAP only for login. Hence the two Authentication Managers.
We tried the solution in similar questions, however still facing the same problem.
The error code is :
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name
'org.springframework.security.filterChainProxy': Invocation of init
method failed; nested exception is 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 namespace or FilterChainProxy bean
configuration
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<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>
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/application-context.xml
/WEB-INF/spring/security-context.xml
</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher-servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher-servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Application Context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<tx:annotation-driven/>
<jdbc:embedded-database id="datasource" type="H2">
<jdbc:script location="classpath:init.sql"/>
</jdbc:embedded-database>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="datasource"/>
<property name="persistenceUnitName" value="autoservice"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<jpa:repositories base-package="com.oreilly.security.domain.repositories"/>
Security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:component-scan base-package="com.oreilly.security"/>
<bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />
<security:http use-expressions="false" authentication-manager-ref="LDAPAuth">
<security:form-login login-page="/login"
login-processing-url="/login" username-parameter="custom_username"
password-parameter="custom_password" default-target-url="/appointments/"
always-use-default-target="true" authentication-failure-url="/login?error=true" />
<security:logout logout-url="/logout"
logout-success-url="/login?logout=true" />
<security:intercept-url pattern="/appointments/*"
access="ROLE_USER,ROLE_ADMIN" />
<security:intercept-url pattern="/schedule/*"
access="ROLE_ADMIN" />
</security:http>
<security:http use-expressions="false" authentication-manager-ref="IpAuth">
<security:form-login login-page="/login"
login-processing-url="/login" username-parameter="custom_username"
password-parameter="custom_password" default-target-url="/appointments/"
always-use-default-target="true" authentication-failure-url="/login?error=true" />
<security:logout logout-url="/logout"
logout-success-url="/login?logout=true" />
<security:intercept-url pattern="/**"
access="ROLE_USER,ROLE_ADMIN" />
</security:http>
<security:authentication-manager id ="IpAuth">
<security:authentication-provider ref="customAuthenticationProvider"/>
</security:authentication-manager>
<security:authentication-manager id = "LDAPAuth">
<security:ldap-authentication-provider user-search-filter="(uid={0})"
group-search-base="ou=groups" group-search-filter="(uniqueMember={0})"
server-ref="ldapServer" user-context-mapper-ref="contextMapper" role-prefix="ROLE_"
group-role-attribute="cn"/>
</security:authentication-manager>
<security:ldap-server id="ldapServer" url="ldap://localhost:10389/dc=oreilly,dc=com"
manager-dn="uid=admin,ou=system" manager-password="secret"/>
</beans>
Kindly let us know how to get about solving this problem , have been stuck for days :-)
What is telling you is that you have more than one universal pattern matching http sections in your security-config:
<security:http use-expressions="false" authentication-manager-ref="LDAPAuth">
<security:form-login login-page="/login"
login-processing-url="/login" username-parameter="custom_username"
password-parameter="custom_password" default-target-url="/appointments/"
always-use-default-target="true" authentication-failure-url="/login?error=true" />
<security:logout logout-url="/logout"
logout-success-url="/login?logout=true" />
<security:intercept-url pattern="/appointments/*"
access="ROLE_USER,ROLE_ADMIN" />
<security:intercept-url pattern="/schedule/*"
access="ROLE_ADMIN" />
</security:http>
<security:http use-expressions="false" authentication-manager-ref="IpAuth">
<security:form-login login-page="/login"
login-processing-url="/login" username-parameter="custom_username"
password-parameter="custom_password" default-target-url="/appointments/"
always-use-default-target="true" authentication-failure-url="/login?error=true" />
<security:logout logout-url="/logout"
logout-success-url="/login?logout=true" />
<security:intercept-url pattern="/**"
access="ROLE_USER,ROLE_ADMIN" />
</security:http>
If you want to have more than one <security:http /> elements, you must apply a pattern to all of them except the last. For example:
<security:http pattern="/zone1/*" ... />
<security:http pattern="/zone2/*" ... />
...
<security:http ... /> <!-- the last one does not need to apply a pattern -->
According to your config, in your first security:http element you have two intercept-url patterns (/appointmens/**, /schedule/**). You could try to apply a regex matcher to the first security:http element (based in this answer):
<security:http request-matcher="regex" pattern="^/(appointments|schedule)(/(\S)+)+$"
use-expressions="false" authentication-manager-ref="LDAPAuth" >
...
</security:http>
<security:http use-expressions="false" authentication-manager-ref="IpAuth">
...
</security>
Please check the regex to avoid any typo or error I could made.
Looking deeper in your config, I see that the only difference from one to each other is the use of a different authentication-manager. Maybe you could try mixing the two authentication-providers in the same manager, as spring-security is capable of managing more than one authentication provider at the same time. It is able to check the login request to one provider and then to the other (or others) and then act accordingly.
It would be more or less like that:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<context:component-scan base-package="com.oreilly.security"/>
<bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />
<security:http use-expressions="false" authentication-manager-ref="authenticationManager">
<security:form-login login-page="/login"
login-processing-url="/login" username-parameter="custom_username"
password-parameter="custom_password" default-target-url="/appointments/"
always-use-default-target="true" authentication-failure-url="/login?error=true" />
<security:logout logout-url="/logout"
logout-success-url="/login?logout=true" />
<security:intercept-url pattern="/appointments/*"
access="ROLE_USER,ROLE_ADMIN" />
<security:intercept-url pattern="/schedule/*"
access="ROLE_ADMIN" />
<security:intercept-url pattern="/**"
access="ROLE_USER,ROLE_ADMIN" />
</security:http>
<security:authentication-manager id ="authenticationManager">
<security:authentication-provider ref="customAuthenticationProvider"/>
<security:ldap-authentication-provider user-search-filter="(uid={0})"
group-search-base="ou=groups" group-search-filter="(uniqueMember={0})"
server-ref="ldapServer" user-context-mapper-ref="contextMapper" role-prefix="ROLE_"
group-role-attribute="cn"/>
</security:authentication-manager>
<security:ldap-server id="ldapServer" url="ldap://localhost:10389/dc=oreilly,dc=com"
manager-dn="uid=admin,ou=system" manager-password="secret"/>
</beans>
Note I merged your two managers in just one with both authentication providers inside it. Then, I merged too the <security:http /> elements in just one (so that it is not longer necessary to apply any regex nor any other pattern to it) and now there are three <security:intercept-url /> elements, the two from the first original <security:http> and the one from the second.

Spring Security for Static Web Project

I am having issues implementing spring security for static web project.
my web.xml
<?xml version="1.0"?>
<web-app xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4" id="WebApp_ID">
<display-name>Spring Security Application</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value> /WEB-INF/spring-security.xml </param-value>
</context-param>
<!-- 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>
</web-app>
and my spring-security.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/security/html/folder1/**" access="isAnonymous()" />
<security:intercept-url pattern="/security/html/folder2/**" access="isAuthenticated()" />
<security:intercept-url pattern="/security/html/folder3/**" access="hasRole('ROLE_MANAGER')" />
<security:intercept-url pattern="/security/html/folder4/**" access="hasRole('ROLE_ADMIN','ROLE_USER','ROLE_MANAGER')" />
<security:form-login password-parameter="password" username-parameter="username" authentication-failure-url="/login?error" login-page="/login" />
<security:logout logout-success-url="/login?logout" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user1" password="password" authorities="ROLE_USER, ROLE_ADMIN" />
<security:user name="user2" password="password" authorities="ROLE_USER" />
<security:user name="user3" password="password" authorities="ROLE_MANAGER" />
<security:user name="user4" password="password" authorities="ROLE_ADMIN" />
<security:user name="user5" password="password" authorities="ROLE_USER, ROLE_MANAGER" />
<security:user name="user6" password="password" authorities="ROLE_ADMIN, ROLE_MANAGER" />
<security:user name="user7" password="password" authorities="ROLE_ADMIN, ROLE_USER, ROLE_MANAGER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
My folder structure are
src/main/webapp/WEB-INF/web.xml
src/main/webapp/WEB-INF/spring-security.xml
src/main/webapp/WEB-INF/html/folder1/*.html
src/main/webapp/WEB-INF/html/folder2/*.html
src/main/webapp/WEB-INF/html/folder3/*.html
src/main/webapp/WEB-INF/html/folder4/*.html
I do not have any welcome page or any other java files in my project. I need this to deployed in Tomcat server.
Can any one help me out if I am missing anything in config files
I found the answer for my question.
Two mistakes.
I had to remove /security from intercept-url as security is my context root
Move html folder out of WEB-INF

Spring security login-processing-url throws 405 request method POST not supported

i'm working with spring security 3.1.3 in a spring 3.2.0 project. I've configured two entry points for my security using spring security. The idea is to have a url like /enterprise_login where enterprise users should log in and other url like /login where normal users do their log in action. In my security configuration i've the next code
<security:global-method-security jsr250-annotations="enabled" pre-post-annotations="enabled" secured-annotations="enabled" />
<security:http pattern="/enterprise/**" auto-config="false" use-expressions="true" authentication-manager-ref="autenticationManagerUserEnterprise">
<security:intercept-url pattern="/enterprise/**" access="hasRole('ROLE_ENTERPRISE')" />
<security:intercept-url pattern="/enterprise_login" access="isAnonymous()" />
<security:form-login login-page="/enterprise_login" default-target-url="/" authentication-failure-url="/empresas_login_error" login-processing-url="/enterprise_login_process" />
<security:logout logout-success-url="/" delete-cookies="JSESSIONID"/>
<security:remember-me user-service-ref="enterpriseAuthenticationProvider"/>
<security:session-management invalid-session-url="/">
<security:concurrency-control max-sessions="2" error-if-maximum-exceeded="true" />
</security:session-management>
</security:http>
<security:http pattern="/**" auto-config="false" use-expressions="true" authentication-manager-ref="autenticationManagerUser">
<security:intercept-url pattern="/**" access="permitAll" />
<security:form-login login-page="/login" default-target-url="/" authentication-failure-url="/login_error" />
<security:logout logout-success-url="/" delete-cookies="JSESSIONID"/>
<security:remember-me user-service-ref="UserAuthenticationProvider"/>
<security:session-management invalid-session-url="/">
<security:concurrency-control max-sessions="2" error-if-maximum-exceeded="true" />
</security:session-management>
</security:http>
<security:authentication-manager id="autenticationManagerUserEnterprise">
<security:authentication-provider user-service-ref="enterpriseAuthenticationProvider">
<security:password-encoder hash="plaintext"></security:password-encoder>
</security:authentication-provider>
</security:authentication-manager>
<security:authentication-manager id="autenticationManagerUser">
<security:authentication-provider user-service-ref="UserAuthenticationProvider">
<security:password-encoder hash="plaintext"></security:password-encoder>
</security:authentication-provider>
</security:authentication-manager>
<bean id="enterpriseAuthenticationProvider" class="com.test.security.enterpriseAuthenticationProvider"></bean>
<bean id="UserAuthenticationProvider" class="com.test.security.UserDetailsServiceImp"></bean>
Then when I go to /enterprise_login form and submit the login data I get a "HTTP 405 - Request method 'POST' not supported" throwed by tomcat in the url /enterprise_login_process (the url configured to act as login-processing-url. I can't figure out where the problem is, any help is really appreciated.
PD: My web.xml looks like:
<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>AT-2</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-config.xml
</param-value>
</context-param>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>tutorial.root</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<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>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-config.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
The issue is that the first configuration currently only matches on URLs that start with "/enterprise/" and the URL to process authentication is configured as "/enterprise_login_process". This means that submitting a POST to "/enterprise_login_process" will submit to the second configuration which is not trying to authenticate "/enterprise_login_process".
To fix this you need to ensure the http#pattern and the login-processing-url are aligned. For example:
<security:http pattern="/enterprise/**"
auto-config="false"
use-expressions="true"
authentication-manager-ref="autenticationManagerUserEnterprise">
<security:intercept-url pattern="/enterprise/login"
access="isAnonymous()" />
<security:intercept-url pattern="/**"
access="hasRole('ROLE_ENTERPRISE')" />
<security:form-login login-page="/enterprise/login"
default-target-url="/"
authentication-failure-url="/enterprise/login?error"
login-processing-url="/enterprise/login_process" />
<security:logout logout-success-url="/"
delete-cookies="JSESSIONID"/>
<security:remember-me
user-service-ref="enterpriseAuthenticationProvider"/>
<security:session-management invalid-session-url="/">
<security:concurrency-control max-sessions="2"
error-if-maximum-exceeded="true" />
</security:session-management>
</security:http>
You will observe that I modified the code to ensure all URLs within the block start with "/enterprise/". This also means that you will need to ensure that your login form for enterprise is updated to POST to "/enterprise/login_process".

Spring-security :The page isn't redirecting properly

i want to use spring security from spring in m web application so here's the configuration:
This is the spring-security.xml :
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http auto-config="true" use-expressions="false">
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/authentication" login-processing-url="/static
/j_spring_security_check" authentication-failure
url="/login?login_error=t" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service id="userService"
data-source-ref="DataSource"
users-by-username-query="select name, password, true from person where name=?"
authorities-by-username-query="select name,'ROLE_USER' from person where
name=?" />
</authentication-provider>
</authentication-manager>
Web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns
/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>OTV_JSF_PrimeFaces_Spring_Hibernate</display-name>
<!-- Spring Context Configuration' s Path definition -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- The Bootstrap listener to start up and shut down Spring's root
WebApplicationContext. It is registered to Servlet Container -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<!-- Project Stage Level -->
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<!-- Welcome Page -->
<welcome-file-list>
<welcome-file>/home.xhtml</welcome-file>
</welcome-file-list>
<!-- JSF Servlet is defined to container -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Mapping with servlet and url for the http requests. -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<!-- 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>
</web-app>
here's the application :
When i run the application , this URL is opened
http://localhost:8089/MVNOONPProject/authentication and i get this error :
`The page isn't redirecting properly
Firefox has detected that the server is redirecting the request for this address in
a way that will never complete.`
I'm sure it's a problem with the web.xml . But i didn't find how to solve it .
Thank you in advance
It usually makes sense to protect only proper web pages which would be JSF rendered ones here. For sure you should not intercept all urls or else login won't be possible. This assumes you have a working login page under /authentication.
<http auto-config="true" use-expressions="false">
<intercept-url pattern="/**/*.faces" access="ROLE_USER" />
<intercept-url pattern="/**/*.jsf" access="ROLE_USER" />
<intercept-url pattern="/**/*.xhtml" access="ROLE_USER" />
<form-login login-page="/authentication" login-processing-url="/static
/j_spring_security_check" authentication-failure
url="/login?login_error=t" />
</http>
Try 2 things
Add
< intercept-url pattern="/authentication" access="IS_AUTHENTICATED_ANONYMOUSLY" />
Add default-target-url in your form-login tag
default-target-url='/home.xhtml'
One more thing you are using a custom login page and your http auto-config="true" change it to false if you are using custom login page
So your security config should be like this (login-processing-url is also not needed)
<http auto-config="false" use-expressions="false">
<intercept-url pattern="/**" access="ROLE_USER" />
< intercept-url pattern="/authentication" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<form-login login-page="/authentication" authentication-failure
url="/login?login_error=t" default-target-url='/home.xhtml'/>
Thats because , you spring security configuration redirects cyclically.
try this ,
<http auto-config="true" use-expressions="false">
<intercept-url pattern="/login.jsp*" filters="none"/>
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/authentication" login-processing-url="/static
/j_spring_security_check" authentication-failure
url="/login?login_error=t" />
</http>
Edit
<http auto-config="true" use-expressions="false">
<intercept-url pattern="/authentication" filters="none"/>
<intercept-url pattern="/login.jsp*" filters="none"/>
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/authentication" login-processing-url="/static
/j_spring_security_check" authentication-failure
url="/login?login_error=t" />
</http>
Since the pattern="/**" intercepts all URL requests including login page itself, any user has to be logged in even to access the login page.. so after hours of trying, following did the trick for me..
<intercept-url pattern="/login**" access="ROLE_ANONYMOUS" />
<intercept-url pattern="/resources/**" access="ROLE_ANONYMOUS, ROLE_USER, ROLE_ADMIN" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login
login-page="/login"
default-target-url="/home"
authentication-failure-url="/login?error=true" />
Notice,
the order of intercept-url tags
pattern="/**" basically intercepts all url request, even resources like css and image file. that's why the second line is needed.
Other answers were quite close but weren't working with Spring MVC 3.2.3.RELEASE version
I think this might cause other problems in the future, so the better approach might be,
<intercept-url pattern="/admin*" access="ROLE_ADMIN" />
<intercept-url pattern="/user*" access="ROLE_USER, ROLE_ADMIN" />
<form-login
login-page="/login"
default-target-url="/home"
authentication-failure-url="/login?error=true" />

Max Concurrent sessions doesn't apply to same browser

i have configured max sessions to be 1 and set error-if-maximum-exceeded=true
i noticed two issues:
1- session-authentication-error-url doesn't work if there's authentication-failure-handler-ref configured, the authentication-failure-handler-ref takes precedence and then you will have to handle SessionAuthenticationException there and make needed logic.
2- if i have open session in chrome and try to login in firefox i get the SessionAuthenticationException but if i tried to login again in chrome (which already has an open session) i get login successful and doesn't get the SessionAuthenticationException
should i prevent the user from seeing login page if he's already authenticated ?
if that's correct, please advise how to do that.
i usually check for authenticated user as follows:
if(!SecurityContextHolder.getContext().getAuthentication().getPrincipal().equals("anonymousUser")){
// logged in user
}
here's my current configuration:
1- web.xml:
<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>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
2- applicationSecurity.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<constructor-arg value="256"/>
</bean>
<bean id="saltSource"
class="org.springframework.security.authentication.dao.ReflectionSaltSource">
<property name="userPropertyToUse" value="username" />
</bean>
<bean id="customUserDetailsService"
class="com.myapp.faces.web.services.CustomUserDetailsService" />
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="customUserDetailsService">
<security:password-encoder ref="passwordEncoder">
<security:salt-source ref="saltSource" />
</security:password-encoder>
</security:authentication-provider>
</security:authentication-manager>
<bean id="loginSuccessHandler" class="com.myapp.faces.web.services.LoginSuccessHandler">
<property name="defaultTargetUrl" value="/dashboard"/>
</bean>
<bean id="loginFailureHandler" class="com.myapp.faces.web.services.LoginFailureHandler" />
<security:http use-expressions="true" auto-config="true" >
<security:intercept-url pattern="/j_spring_security_check" access="permitAll" />
<security:intercept-url pattern="/faces/javax.faces.resource/**" access="permitAll"/>
<security:intercept-url pattern="/xmlhttp/**" access="permitAll" />
<security:intercept-url pattern="/resources/**" access="permitAll" />
<security:intercept-url pattern="**/faces/javax.faces.resource/**" access="permitAll" />
<security:intercept-url pattern="**/xmlhttp/**" access="permitAll" />
<security:intercept-url pattern="**/resources/**" access="permitAll" />
<security:intercept-url pattern="/login" access="permitAll"/>
<security:intercept-url pattern="/**" access="isAuthenticated()" />
<security:form-login
login-processing-url="/j_spring_security_check"
login-page="/login"
authentication-failure-handler-ref="loginFailureHandler"
authentication-success-handler-ref="loginSuccessHandler" />
<security:logout />
<security:session-management session-authentication-error-url="/login?error=3">
<security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
</security:session-management>
</security:http>
</beans>
I personally do it this way.
#RequestMapping(method=RequestMethod.GET)
public String login(Authentication authentication)
{
if((authentication != null) && authentication.isAuthenticated())
{
return "redirect:dashboard";
}
return viewResolver.getView(ViewConstants.LOGIN_PAGE);
}
The method above is used for requesting the login page.
I don't think there is a way to do it using only configuration though. I may be wrong.
EDIT :
Check this link

Resources