How to temporarily disable Spring Security in Spring Web App - spring

First, I am a complete noob when it comes to Spring. An application was left to me to work on by a colleague who is now on vacation. He told me to leave security alone, as the final approach is not decided yet, and just develop the rest of the application.
However security is enabled and prevents access to the main web page. I've checked several documents including
Disable Spring Security from spring-security.xml file
Disable Basic Authentication while using Spring Security Java configuration
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-security.html
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-security.html
without finding an answer that works.
I did the following:
Added index.html to <welcome-file-list> in web.xml. This directs me to the login page which was already included in the package I took over. So, I figured I could simply disable security.
In the spring security.xml added the attribute security="none". Now I no longer get the login page. I get a blank page.
In web.xml disabled
<!-- <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> -->
Still get blank page.
I see lots of other advice, but it assumes a lot more Spring knowledge than I currently have.
For example in the 4th link above I see:
If you define a #Configuration with #EnableWebSecurity anywhere in
your application it will switch off the default webapp security
settings in Spring Boot.
I don't know what they mean. I assume this means to put these annotations on some method somewhere, but I can't believe that this can go ANYWHERE in any java class in the application. Is there an example of doing this?
Can someone point me in the correct direction? Thanks.

Comment out <intercept-url pattern="" access="" /> tags in security XML file and give access to all the pages. This should work.

This seemed to work (in spring-security.xml)
<!-- <intercept-url pattern="/**" access="hasRole('ROLE_USER')" /> -->
<intercept-url pattern="/**" access="permitAll" />

check your web.xml or your appContext.xml to find where is loaded the spring security.xml beans(it will be like <import resource=../spring security.xml>) and comment this out , also check the beans that are loaded from there before disabling it , cause it might redirecting or whatever

Related

Security Context Returning Null value in Web App

In my web application the security context is with a value of (org.springframework.security.core.context.SecurityContextImpl#ffffffff: Null authentication)
and on doing some search I found something like :
"Look to see if you have any references to SecurityContextHolder in your code. If you do, ensure that you have the SecurityContextPersistenceFilter place on any URLs that could invoke that code."
In my Project this filter is created but I dont know what exactly this means.
Can someone please give me some advice?
Thanx in advance.
Ensure that you have something like
<filter>
<filter-name>springSecurityFitler</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSeurityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
in your web.xml descriptor file.
See http://docs.spring.io/spring-security/site/docs/4.0.x/reference/html/security-filter-chain.html for more info.
Also note that in a Vaadin application you usually want to exclude some paths in security context file, for example:
<http pattern="/VAADIN/**" security="none" />
<http pattern="/HEARBEAT/**" security="none" />

Allow Specific URL patterns to bypass Spring Security Login

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

Spring Security 3.2 CSRF support for multipart requests

We have been using Spring Security with our application for a few years now. Last week we upgraded Spring Security from version 3.1.4 to 3.2.0. The upgrade went fine and we did not find any errors post the upgrade.
While looking through the Spring Security 3.2.0 documentation we came across the newly added features around CSRF protection and security headers. We followed the instructions in the Spring Security 3.2.0 documentation to enable CSRF protection for our protected resources. It works fine for regular forms but does not work for multipart forms in our application. On form submission, CsrfFilter throws an Access Denied error citing the absence of a CSRF token in the request (determined through DEBUG logs). We have tried using the first option suggested in the Spring Security documentation for making CSRF protection work with multipart forms. We do not want to use the second suggested option as it leaks CSRF tokens through the URLs and poses a security risk.
The relevant part of our configuration based on the documentation is available as a Gist on Github. We are using Spring version 4.0.0.
Note that we have already tried the following variations without success:
Not declaring the MultipartFilter in web.xml.
Not setting the resolver bean name for the MultipartFilter in web.xml.
Using the default resolver bean name filterMultipartResolver in webContext.xml.
UPDATE: I have confirmed that the documented behaviour does not work even with a single page sample app. Can anyone confirm that the documented behaviour works as expected? Is there an example working application that can be used?
I was able to resolve this with help from the Spring Security team. I have updated the Gist to reflect a working configuration. I had to follow the steps given below in order to get everything to work as expected.
1. Common Step
Add a MultipartFilter to web.xml as described in the answer by #holmis83, ensuring that it is added before the Spring Security configuration:
<filter>
<display-name>springMultipartFilter</display-name>
<filter-name>springMultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>springMultipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<display-name>springSecurityFilterChain</display-name>
<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>ERROR</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
2.1. Using Apache Commons Multipart Resolver
Ensure that there is an Apache Commons Multipart Resolver bean named filterMultipartResolver in the root Spring application context. I will stress this again, make sure that the Multipart Resolver is declared in the root Spring Context (usually called applicationContext.xml). For example,
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:springWebMultipartContext.xml
</param-value>
</context-param>
springWebMultipartContext.xml
<beans xmlns="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.xsd">
<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000" />
</bean>
</beans>
Make sure that the bean is called filterMultipartResolver as any other bean name is not picked up by MultipartFilter configured in web.xml. My initial configuration was not working because this bean was named multipartResolver. I even tried passing the bean name to MultipartFilter using web.xml init-param but that did not work either.
2.2. Using Tomcat Multipart support
Tomcat 7.0+ has in-built multipart support, but it has to be explicitly enabled. Either change the global Tomcat context.xml file as follows or include a local context.xml file in your WAR file for this support to work without making any other changes to your application.
<Context allowCasualMultipartParsing="true">
...
</Context>
After these changes using Apache Commons Multipart Resolver our application is working so far on Tomcat, Jetty and Weblogic.
This part:
<filter-mapping>
<filter-name>multipartFilter</filter-name>
<servlet-name>/*</servlet-name>
</filter-mapping>
Should be:
<filter-mapping>
<filter-name>multipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
It is an error in Spring Security 3.2.0 documentation. The bug has been reported and will be fixed in upcoming version.
After struggling with this issue a bit, I found a much easier solution by just using the Request Header defined in Spring Security instead of trying to get the CSRF token embedded as a part of the multipart content.
Here is a simple way I setup the header using an AJAX library for file upload in my jsp:
var uploader = new AjaxUpload({
url: '/file/upload',
name: 'uploadfile',
multipart: true,
customHeaders: { '${_csrf.headerName}': '${_csrf.token}' },
...
onComplete: function(filename, response) {
...
},
onError: function( filename, type, status, response ) {
...
}
});
Which in turn sent the multipart request with header:
X-CSRF-TOKEN: abcdef01-2345-6789-abcd-ef0123456789
Their recommendations for embedding into <meta /> tags in the header would also work just fine by halting the request on submit, adding the header via javascript, and then finish submitting:
<html>
<head>
<meta name="_csrf" content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}"/>
<!-- ... -->
</head>
<body>
<!-- ... -->
<script>
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
// Do whatever with values
</script>
</body>
</html>
More info: Spring Security - CSRF for AJAX and JSON Requests
Find most answer is answered server years ago.
If you need
Passing CSRF tokens with RestTemplate
This blog is quite enlightening https://cloudnative.tips/passing-csrf-tokens-with-resttemplate-736b336a6cf6
In Spring Security 5.0.7.RELEASE
https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-multipart
There are two options to using CSRF protection with
multipart/form-data. Each option has its tradeoffs.
-Placing MultipartFilter before Spring Security
-Include CSRF token in
action
For short, the first option is safer, the latter is easier.
Specifying the MultipartFilter before the Spring Security filter
means that there is no authorization for invoking the MultipartFilter
which means anyone can place temporary files on your server. However,
only authorized users will be able to submit a File that is processed
by your application. In general, this is the recommended approach
because the temporary file upload should have a negligible impact on
most servers.
To ensure MultipartFilter is specified before the Spring Security
filter with java configuration, users can override
beforeSpringSecurityFilterChain as shown below:
public class SecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
#Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
}
To ensure MultipartFilter is specified before the Spring Security
filter with XML configuration, users can ensure the
element of the MultipartFilter is placed before the
springSecurityFilterChain within the web.xml as shown below:
<filter>
<filter-name>MultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>MultipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Another option
If allowing unauthorized users to upload temporary files is not
acceptable, an alternative is to place the MultipartFilter after the
Spring Security filter and include the CSRF as a query parameter in
the action attribute of the form. An example with a jsp is shown below
<form action="./upload?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">
The disadvantage to this approach is that query parameters can be
leaked. More genearlly, it is considered best practice to place
sensitive data within the body or headers to ensure it is not leaked.

JSF and Spring securtiy Integration [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Spring Security Authentication is not working as expected in my configuration
I tried integrating JSF and spring security i spent almost a day but there is no result
Developed an application using JSF,Spring MVC and Primfaces. I am almost done with my requirements, at the end i planned to integrate the spring security but i could n't and i did enough search on net. I feel it may be bug in related framework.
If anyone of you came across the same please post the solution. I post my approach over here
Step 1:
Created Login.jsp(to have customized login page)
Step 2:
Added below code in my 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>
</filter-mapping>
Step 3:
Created Springsecurity.xml
<sec:global-method-security
secured-annotations="enabled" />
<sec:http auto-config="true" use-expressions="true"
once-per-request="false">
<sec:intercept-url pattern="pages/secured/**"
access="ROLE_USER" />
<sec:form-login login-page="/login.jsp"
default-target-url="/pages/secured/products.xhtml"
authentication-failure-url="/login.html?login_error=1" />
<sec:logout logout-url="/logout" logout-success-url="/login.jsp" />
</sec:http>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider>
<sec:user-service>
<sec:user name="vijay" authorities="ROLE_USER" password="vijay"/>
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
Executed the application and got the login.jsp as first page since i defind in web.xml. On login authentication its forwarding to the Products.xhtml but i could even access the rest of pages which all are comes under the secured folder with out logging in.
Please suggest a better approach or other alternatives.
For your access attribute have your tried. Your first slash was missing in the pattern.
<sec:intercept-url pattern="/pages/secured/**"
access="hasRole('ROLE_USER')" />

#Secured does not work in controller, but intercept-url seems to be working fine

It doesn't look like #Secured on methods in my #Controller are being read. When security filtering based on sec:intercept-url is being used, this seems to be working just fine. The following code results in Spring Security giving me this log entry:
DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Public object - authentication not attempted
web.xml
contextConfigLocation
/WEB-INF/spring/root-context.xml
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/appServlet/servlet-context.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Filter 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-context.xml holds the configuration of the viewResolvers and all the marshalling. This configuration is annotation-driven.
root-context.xml
<sec:global-method-security secured-annotations="enabled" />
<sec:http auto-config="true">
<sec:http-basic/>
</sec:http>
<!-- Declare an authentication-manager to use a custom userDetailsService -->
<sec:authentication-manager>
<sec:authentication-provider
user-service-ref="userDetailsService">
<sec:password-encoder ref="passwordEncoder" />
</sec:authentication-provider>
</sec:authentication-manager>
<bean
class="org.springframework.security.authentication.encoding.PlaintextPasswordEncoder"
id="passwordEncoder" />
<sec:user-service id="userDetailsService">
<sec:user name="john" password="john" authorities="ROLE_USER, ROLE_ADMIN" />
<sec:user name="jane" password="jane" authorities="ROLE_USER" />
</sec:user-service>
PingController.java
#Controller
public class PingController {
#Secured("ROLE_ADMIN")
#RequestMapping(value = "/ping", method = RequestMethod.GET)
public void ping() {
}
}
This doesn't seem to have any relation to which authentication method I'm using, so the basic-http-tag can be overlooked.
I have this idea that the #Secured doesn't work because of it being used in another context than the root-context.xml in which the security is being configured. I've tried to move this configuration to the servlet-context.xml, but it doesn't seem to reach the springSecurityFilterChain. Any thoughts on the problem and and my theory?
You are right, <global-method-security> is applied at per-context basis. However, you don't need to move the whole security configuration to servlet-context.xml, just add a <global-method-security> element to it.
See Spring Security FAQ (emphasis mine). If you apply pointcuts to service layer you only need to set <global-method-security> in your app's security context.
In a Spring web application, the application context which holds the
Spring MVC beans for the dispatcher servlet is often separate from the
main application context. It is often defined in a file called
myapp-servlet.xml, where “myapp” is the name assigned to the Spring
DispatcherServlet in web.xml. An application can have multiple
DispatcherServlets, each with its own isolated application context.
The beans in these “child” contexts are not visible to the rest of the
application. The “parent” application context is loaded by the
ContextLoaderListener you define in your web.xml and is visible to all
the child contexts. This parent context is usually where you define
your security configuration, including the
element). As a result any security constraints applied to methods in
these web beans will not be enforced, since the beans cannot be seen
from the DispatcherServlet context. You need to either move the
declaration to the web context or moved the
beans you want secured into the main application context.
Generally we would recommend applying method security at the service
layer rather than on individual web controllers.

Resources