A Universal Match Pattern ('/**') is Defined Before Other Patterns - spring

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

Related

Spring MVC make a rest controller without suffix in URL. My other controllers need to have suffix

I am running a Spring Project which is a combination of Spring MVC and Spring boot. Its configuration has set all the controllers must need to use .html in the URL suffix. Now I need to connect with a third party that shared a predefined URL that I have to make where URL does not have any suffixes.
My system URL https://mysystem.com/api/urls.html
I need to have https://mysystem.com/thrid_party_string
I am facing trouble configuring. Both at the same time. how can I manage?
Note: I cannot change existing controllers since they are already in us for many services.
My web.xml file
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_3_0.xsd"
version="3.0">
<display-name>test</display-name>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webapp.test</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContextService.xml</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jExposeWebAppRoot</param-name>
<param-value>false</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>
<!-- filter -->
<filter>
<filter-name>Set Character Encoding</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-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>*.asx</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>*.m3u8</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>cors</filter-name>
<filter-class>some.com.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Standard Action Servlet Configuration -->
<servlet>
<servlet-name>spring-mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc-dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<!-- Standard Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>spring-mvc-dispatcher</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/general_error.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/general_error_500.html</location>
</error-page>
</web-app>
By using spel(Spring expression language) you can set prefix for each controller
#Controller
#RequestMapping(path = "${apiPrefix}/users")
public class UserController {
}
Then, we simply specify the property value in our application.properties:
apiPrefix=/api
for more information you can see its
documentatihttps://www.baeldung.com/spring-boot-controllers-add-prefixon
Normally if you're the one providing the service, the caller needs to adjust to your URL patterns, not the other way around.
That said... it appears recent servlet specs can have more than one url-pattern. If the desired REST URLs don't have a common pattern of their own, like /api/xxx, you might have to bind the dispatcher to / and expect a lot of URLs that don't match the REST ones or *.html to just produce internal 404 errors

Spring security +Jsf2

I'm newbie at spring security it's my first use to spring security at me APP
My application has developed using jsf2 , primefaces , spring , hibernate
after developing it I'm trying to integrate it with Spring security framework
there are two problems
1- when access any URL from app , my app isn't navigate him to login page
2- when one user logged in and someone else tried to access the application in the same time , he see that someone is logged in and conflicts are happenned and at end throw exceptions meaning there is no new created session for the second user
My applicationContext-Security.xml is
<context:property-placeholder location="classpath:resources/jdbc.properties" />
<!-- For Spring auto wiring -->
<tx:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="main.com.zc.attSys" />
<tx:annotation-driven transaction-manager="hibernateTransactionManager" />
<http use-expressions="true">
<form-login login-page="/pages/courseFeedBack/ask/login.xhtml"
authentication-failure-url="/pages/courseFeedBack/ask/login.xhtml" />
</http>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
</authentication-provider>
</authentication-manager>
</beans:beans>
my web.xml is :
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<!-- Add Support for Spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>com.sun.faces.conf
ig.ConfigureListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<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>
<!-- <context-param> <param-name>primefaces.THEME</param-name> <param-value>none</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>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
</web-app>
any help please ?

Spring Security 3.2: #Secured annotations not taken into account

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.

Struts2 and BlazeDS on Spring3

I would like to configure settings both blazeds and Struts2 running on springframework at the same time.
I configured web.xml like below. But one works another doesn't work.
Becaouse Struts2 filters AMF protocol.
If I comment out one of them, It works property. vice versa.
Is there any way to configure struts2 settings to work both?
web.xml
<!-- Struts2 Settings
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>struts.devMode</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
<!-- Flex Settings -->
<listener>
<listener-class>flex.messaging.HttpFlexSession</listener-class>
</listener>
<!-- MessageBroker Servlet -->
<servlet>
<servlet-name>MessageBrokerServlet</servlet-name>
<display-name>MessageBrokerServlet</display-name>
<servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
<init-param>
<param-name>services.configuration.file</param-name>
<param-value>/WEB-INF/flex/services-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MessageBrokerServlet</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
For Devlopment
JDK1.6
Spring3.0.1
Tomcat6.0
Flex4.6
You could exclude some patterns from Struts2 filter. Define struts.action.excludePattern constant in your struts.xml file.
<constant name="struts.action.excludePattern" value=".*unfiltered.*,.*\\.nofilter"/>

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