Can Spring help to prevent caching of html pages on the browser? - spring

I have a Java/Spring 3.x webapp that uses ExtJS and I use the Sencha Architect to create the front end which results in an automatically generated app.html file that loads in the JS and CSS resources that looks like this:
<!DOCTYPE html>
<!-- Auto Generated with Sencha Architect -->
<!-- Modifications to this file will be overwritten. -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ui</title>
<script src="ext/ext-all.js"></script>
<script src="ext/ext-theme-neptune.js"></script>
<link rel="stylesheet" href="ext/resources/ext-theme-neptune/ext-theme-neptune-all.css">
<link rel="stylesheet" href="css/custom.css">
<script type="text/javascript" src="app.js"></script>
</head>
<body></body>
</html>
I want to protect this html file with Spring security and this seems to work except that it is often cached in the browser so that it appears to reload even when the user is not logged in. Here is my Spring XML that configures security for my webapp:
<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.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/ui/app.html" access="hasRole('ROLE_USER')" />
<intercept-url pattern="/ui/**" access="permitAll" />
<form-login
login-page="/login"
default-target-url="/ui/app.html"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/login?logout" />
<csrf/> <!-- enable csrf protection -->
</http>
<authentication-manager>
<authentication-provider >
<user-service>
<user name="test" password="test" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
As you can see I have configured it to protect the ui/app.html resource as well as redirect to that page after log in. This works fine until the browser caches the page and causes confusion when the user is logged out and tries to access the same URL.
I was wondering if Spring MVC could be used to load the page via a controller, perhaps modifying the HTTP headers to force the page to expire, but as this is a page that is normally delivered directly by the servlet container and not MVC I'm not sure how I would configure that.
I'd also like to be able to leave my app.html file in-situ as it uses resources that are relative to it, and it's also easier to leave it there when working with Sencha Architect.

This will prevent browser caching:
<http>
<!-- ... -->
<headers>
<cache-control />
</headers>
</http>
It adds Cache-Control, Pragma and Expires headers for every response. More information can be found in reference documentation, section Security HTTP Response Headers.
Update: This answer was written for version 3.2 of Spring Security. As of version 4, these headers are included by default.

You can choose one of the below which depends on how your application is going to serve the resource requests.
Using Spring Security
http://docs.spring.io/spring-security/site/docs/current/reference/html/headers.html#headers-cache-control
Using Extjs
http://www.sencha.com/forum/showthread.php?257086-Is-there-a-simple-way-to-disable-caching-for-an-entire-ExtJS-4-application
Using HTML
http://www.htmlgoodies.com/beyond/reference/article.php/3472881

Related

Spring Security this kind of http://localhost:8080/WEB/edit-employee/{ID} url not authenticating

I have configured one spring security context for my project by using intecept-url i am able to authenticate all URLS but when i pass some ID over URL authentication is not happening.
<intercept-url pattern="/**" access="isAuthenticated()"/>
Working URLS
http://localhost:8080/WEB/add-employee
http://localhost:8080/WEB/view-employee
Not working URLS
http://localhost:8080/WEB/edit-employee/1
http://localhost:8080/WEB/edit-employee/2
1 and 2 are the ID iam passing over URL the above URL patterns are not working (that means when i passing ID over URL)
And i have tried many combinations in intercept-url but i am not getting the correct result.
<http use-expressions="true">
<intercept-url pattern="/**" access="isAuthenticated()"/> <!-- this means all URL in this app will be checked if user is authenticated -->
<!-- We will just use the built-in form login page in Spring -->
<form-login login-page="/" login-processing-url="/j_spring_security_check" default-target-url="/home" authentication-failure-url="/"/>
<logout logout-url="/logout" logout-success-url="/"/> <!-- the logout url we will use in JSP -->
</http>
Delete the line <intercept-url pattern="/edit-employee/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/> to disallow anonymous access to that URL.

InvalidCsrfTokenException when submitting a form

I'm working in a spring based web application (version 4.1.6.RELEASE, spring security 4.0.0.RELEASE) and I'm getting the error InvalidCsrfTokenException: Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'. after submitting a form (POST method). According to the spring's documentation "Spring Security automatically inserts a CSRF form field for any <form:form> tags you use", so why I'm getting this exception?
Thanks in advance.
This is my spring security configuration:
<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-4.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd">
<http use-expressions="true" disable-url-rewriting="true">
<headers>
<frame-options/>
<xss-protection/>
<hsts/>
</headers>
<csrf/>
<intercept-url pattern="/welcome" access="isAuthenticated()" />
<!-- some others urls to intercept -->
<form-login login-page="/login" default-target-url="/welcome"
authentication-failure-url="/loginfailed" />
<logout logout-success-url="/logout" />
<session-management>
<concurrency-control max-sessions="1" expired-url="/login" />
</session-management>
</http>
And this is the definition of my form (excluding the fields it contains):
<form:form action="myaction" method="post" enctype="multipart/form-data" id="formId" modelAttribute="myBean">
</form:form>
Any help will be appreciated
The issue is arising because you are using a multi-part form. Please see the accepted answer here:
Spring CSRF token does not work, when the request to be sent is a multipart request

how to delete remember me cookie in spring security

I was wondering how to the remove the remember me cookie when using spring remember me services.
I am using the default remember me cookie name
I came across the following documentation in spring to delete the JSESSION.
<http>
<logout delete-cookies="JSESSIONID" />
</http>
But is it possible to do something like below to delete the remember me cookie as well
I don't have a logout controller and i have the following configuration in the spring xml.
<http use-expressions="true">
<!-- Authentication policy -->
<form-login login-page="/signin" login-processing-url="/signin/authenticate" authentication-failure-url="/signin?param.error=bad_credentials" />
<logout logout-url="/signout" delete-cookies="JSESSIONID" />
....................
I don't think you have to manually delete the remember-me cookie. The AbstractRememberMeServices implements the LogoutHandler interface, so it will receive a call-back from the LogoutFilter, and makes sure the remember-me cookie is cancelled on logout.

Multiple login forms, different authentication managers - latest spring security

I have a web application secured with Spring Security that needs two separate login forms. These two login forms need to be totally independent. I mean different login form, different url paths, be able to have a different authentication manager for each one too.
I have looked all over google and there are some ways to do this, but I have read and see some changes the last couple of weeks should make it easy to do this in the latest snapshot versions of the code.
First of all, as this bug is complete SEC-1171 we can now have multiple namespace elements to support multiple filter chain configurations.
Secondly, as this other bug shows SEC-1847 we are now able to select a custom authentication manager for each http tag.
The problem is that I have downloaded, compiled and everything but my xsd doesn't allow me to create a custom auth manager for each http tag, I also get errors whenever I try to change the login processing url or whenever I try to use a remember me key for each login form.
I started doing something like this:
<!-- Configure realm for administration users -->
<http pattern="/admin/**" auto-config="true" disable-url-rewriting="true" >
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<form-login login-page="/adminLogin.htm" default-target-url="/"
login-processing-url="/loginProcessing"
authentication-failure-url="/adminLogin.htm?error" />
<logout invalidate-session="true" logout-success-url="/" logout-url="/logout" />
<remember-me key="******" user-service-ref="userDetailsService" />
</http>
<!-- Configure realm for standard users -->
<http auto-config="true" disable-url-rewriting="true">
<intercept-url pattern="/user/**" access="ROLE_USER" />
<form-login login-page="/login.htm" default-target-url="/"
login-processing-url="/loginProcessing"
authentication-failure-url="/login.htm?error" />
<logout invalidate-session="true" logout-success-url="/" logout-url="/logout" />
<remember-me key="******" user-service-ref="userDetailsService" />
</http>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="userDetailsService" >
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
<authentication-provider>
<password-encoder ref="passwordEncoder"/>
<user-service>
<user name="ned" password="****" authorities="ROLE_USER" />
<user name="tom" password="****" authorities="ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
I am using the latest snapshot of Spring Security 3.1.
As I said the ideal would be to be able to have two different login forms totally independent using the "new" way that was changed recently on these bugs.
Anybody has worked with this or has any idea?
Thanks in advance.
As you can see in commit log of October 30th'11 (2f67bb3) for SEC-1847, the authentication-manager-ref attribute can be added in http and global-method-security.
Ritesh, you are right, however, if I try to configure authentication-manager-ref in the http element, the follow exception occurs: org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'authentication-manager-ref' is not allowed to appear in element 'security:http'.
In header of my security.xml, I'm using http://www.springframework.org/schema/security/spring-security-3.1.xsd. If I browse to this URL, the xsd loaded declares the attribute authentication-manager-ref to the http element, but the xsd in spring-security-config-3.1.0.RC2.jar doesn't.
I created an issue in springsource jira-> https://jira.springsource.org/browse/SEC-1879 .
I replaced the xsd contained in spring-security-config-3.1.0.RC3.jar with a correct one and org.xml.sax.SAXParseException doesn't occur anymore, but it's not possible to declare two authentication-manager beans in security.xml.

How to use mvc:resources tag

I am using Spring Security 3. I have files unders /js, /css and /img folders and imports them HTML files. I want to serve them with mvc:resource because I can add expire-head easily and I think it gives a url-rewriting ability. However I am so new to Spring Security and don't know the purpose of it and how can I use it?
An example usage at my HTML webpages:
<link rel="stylesheet" href="/css/main.css"/>
The mvc:resources tag has nothing to do with Spring Security - it tells Spring MVC to not pass those resources through the RequestDispatcher servlet, but to serve them up directly. Instead, you want to exclude those same directories from Spring Security resource controls, as follows:
<intercept-url pattern="/css/**" filters="none"/>
<intercept-url pattern="/js/**" filters="none"/>
<intercept-url pattern="/img/**" filters="none"/>
See http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html#ns-minimal for full details.

Resources