How can I use boolean parameters from application.properties in spring security context configuration xml file? - spring

I am trying to use a boolean parameter from my application.properties in my spring-security configuration xml file.
I don't know why I can use not-boolean parameters, but I get an error for boolean.
How can I use boolean parameters?
Here is my application.properties:
JDBC_CONNECTION_STRING=jdbc:mysql://localhost:3306/schema?user=username&password=password
protocol=http
USE_SECURE=false
My spring-security.xml is:
< remember-me user-service-ref="internalUserDetails" data-source-ref="dataSource" key="this-is-my-key02203452416fw" use-secure-cookie="${USE_SECURE}" />
...
but I get this error:
cvc-datatype-valid.1.2.1: '${USE_SECURE}' is not a valid value for 'boolean'
I have also tried to set USE_SECURE=False but I get the same error again.
How can I use boolean parameters in the spring security configuration xml file?
Here is my web.xml:
<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> Name-MyApp</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- Servlets -->
<servlet>
<servlet-name>MyApp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Servlets Mappings -->
<servlet-mapping>
<servlet-name>MyApp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/servlet-context.xml,
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Filters -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>httpMethodFilter</filter-name>
<servlet-name>MyApp</servlet-name>
</filter-mapping>
<filter>
<filter-name>httpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>

Looks that instead the value the key '${USE_SECURE}' is being passed. I come across similiar issue when I wanted to inistiate Boolean
<bean id="flag" class="java.lang.Boolean">
<constructor-arg value="${FLAG}"/>
</bean>
It works ok with the 'property', so i solved my case in other way. I am not sure if it is a spring bug?

The xsd schema definition of the security namespace only allows boolean values in the use-secure-cookie attribute. If you don't specify one of the allowed literals ("true" or "false"), your xml won't pass the schema validation, and won't get even parsed.
So if you use the security namespace configuration, you won't be able to use external properties to set this value. To prove my point, here is the relevant code snippet from RememberMeBeanDefinitionParser.parse():
String useSecureCookie = element.getAttribute("use-secure-cookie");
if (StringUtils.hasText(useSecureCookie)) {
services.getPropertyValues().addPropertyValue(
"useSecureCookie", Boolean.valueOf(useSecureCookie));
}
As you can see the attribute is straight away converted to boolean, so no mechanism is given any chance to further process the value.
I'm not completely sure, but chances are that this could be fixed by simply relaxing the xsd to allow any string value, and pass that value to the bean definition (services above) without converting it to boolean. Then a PropertyPlaceholderConfigurer could later resolve the given value if it happens to be a property placeholder.
If you want to give it a try, feel free to open a ticket in the Spring Security issue tracker.

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 OAuth2 resource classes not getting called

In reference to the below questions asked on StackOverflow, I have included a class
annotated with #Configuration, #EnableResourceServer and #EnableWebSecurity.
The code is building fine but the control is not going in this class which have been annotated the aforementioned way.
Do I need resource server with Spring Security OAuth2?
I checked that Security filters were disabled in my web.xml. Now, I have enabled them. Even though I am not getting the intended result when I hit my request, I think the initial issue is fixed.
That issue got solved but now I am facing another issue:
HTTP Status 500 - Failed to evaluate expression 'ROLE_USER'
root cause: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'ROLE_USER' cannot be found on object of type 'org.springframework.security.web.access.expression.WebSecurityExpressionRoot' - maybe not public?
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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">
<display-name>hk-pensions</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:META-INF/spring/*.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>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</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>

Autowired not working if used inside class that extends Spring security class

I wasn't able to "autowire" inside a class that extends Spring security class (org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler).
I made it working by adding, in security-config.xml, the following code, already written inside the xml spring configuration file: <context:annotation-config />, <context:component-scan base-package="packagename...."/> and the beans that I autowired.
I have two questions:
Why have I to write twice that code (both inside the xml spring
configuration file and security-config.xml)
Is there a way to tell security-config.xml to "look" for the code
written inside the xml spring configuration file? This way I
shouldn't write the code twice.
Thank you
Try to import your security-beans.xml from your main beans.xml.
Both files should be in the same folder. the import, for example:
<import resource="spring-security.xml"/>
In your web.xml, write something like this:
<!-- to integrate Spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</context-param>
2nd Approach - single beans.xml
Another approach, if you are afraid of imports, is to hold a single beans.xml that will include all beans - both the security beans as well as other beans. In this case, your web.xml will look like this:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
and your spring beans file will be spring-servlet.xml.
HTH.

Restrict URL tampering in Spring Framework 3.1

I am building an application using Spring Framework 3.1
I am having my controllers mapped with url containing path variables that stands for some id.
But I don't want the user to tamper with the url and change the path variable value manually.
I want to restrict them from doing so.
I have already tried using the ShallowEtagHeaderFilter. But its not working the way it suppose to.
I don't know whether I missed any configuration for the filter or its not working at all.
here is my web.xml where I have configured the dispatcher servlet and filter.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<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>
<filter-name>eTagFilter</filter-name>
<filter-class>com.abc.config.EtagFilter</filter-class>
</filter>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>eTagFilter</filter-name>
<servlet-name>dispatcher</servlet-name>
</filter-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
</web-app>
Please help me with this.
Thanks in advance.
I don't understand how ShallowEtagHeaderFilter fits into this picture, I think you misunderstood its functionality. It's supposed to reduce network traffic by taking pages from the browser cache. That's a totally different scenario from yours.
Basically: if you don't want users to tamper with URLs, you will need to have a way to verify that the URL was created by your application, usually a checksum parameter of some sort with an algorithm that's not easy to guess.
e.g. /site/12/user/12345/aB where aB is calculated based on /site/12/user/12345. Now if the user changes the URL to /site/13/user/12345/aB the checksum is wrong and you can send a 404 or a 400 or whatever error you want to send.
I'd probably implement the checksum check as a Filter and write a utility method that creates URLs with checksum based on plain URLs (possibly you'll need a JSP tag as well)

RESTEasy Asynchronous HTTP with Spring MVC

Is there any handy way to use RESTEasy Asynchronous HTTP support (in my case on Tomcat 6) in conjunction with the Spring MVC framework. I've found useful articles on using RESTEasy with Spring, but none that cover asynchronous support, which appears to be a bit of a thorn at present, due to requring a different Servlet class depending on the container (Tomcat6CometDispatcherServlet for Tomcat, for example).
Thanks,
FB
I have created a sample app using Comet, Bayeux, Java, Maven and a Raphael JS frontend and wrote a blog post about it, you can use it as a base for your app, just wrapping the current service code in REST.
http://geeks.aretotally.in/thinking-in-reverse-not-taking-orders-from-yo
Hopefully it will help you.
For anybody interested, I ended up having to use the Tomcat6CometDispatcherServlet in preference to the Spring DispatcherServlet to get my application working.
I still have the Spring ContextLoaderListener in place to create the various beans within my Application Context, but have to use less than ideal means of accessing these from within my Controller classes, which are now JAX-RS annotated rather than Spring MVC annotated. (There are various articles a quick Google will uncover on accessing the Spring context programmatically.)
Here's a cleaned up version of my web.xml (nothing earth-shattering, but perhaps it will have some useful hints for somebody!):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>myapp</display-name>
<description>My App</description>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>myapp.root</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>
<filter>
<filter-name>TrustedIPFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>TrustedIPFilter</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>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>PollServlet</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.Tomcat6CometDispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PollServlet</servlet-name>
<url-pattern>/poll/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/WEB-INF/jsp/uncaughtException.jsp</location>
</error-page>
</web-app>

Resources