Wednesday, May 27, 2015

Spring: Migrating from spring security 3.2.6 to spring security 4.0.0

In this post, i document some changes i went through to successfully migrate from security 3.2.6 to spring security 4.0.0

Changes in <http> in security-config.xml 

In security-config.xml, if you have the <http> section set to:

<http auto-config="true">

For spring security 3.2.6, the following is implied:

  • <http auto-config="true"> is same as <http auto-config="true" use-expressions="false">
For spring security 4.0.0, the following is implied instead:

  • <http auto-config="true"> is same as <http auto-config="true" use-expressions="true"> 
Therefore, need to be careful if you do not use expressions, as in that case you need to set use-expressions="false" in the <http> element

Changes in JSP views 

In spring security 4.0.0, the csrf is enabled by default, which is equivalent to:

<http auto-config="true">
<csrf disabled="false" />
...
</http>

Therefore, some changes must be made in your jsp views as well as ajax calls, as the _csrf fields must be posted back to the spring controller for the codes to work if you are using spring security 4.0.0 instead of spring security 3. Suppose that when using the security 3, I have the following form submit in my jsp view for login:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<html>
<head>
</head>
<body>
<form name="f" action="j_spring_security_check" method="post">
<table>
<tr><td>Username:</td>
<td>
<input type="text" value="j_username" />
</td></tr>

<tr><td>Password: </td>
<td>
<input type="password" value="j_password" />
</td></tr>

<tr><td colspan="2"><input type="submit" value="Submit" /></td></tr>
</table>
</form>
</body>
</html>

Then in spring security 4.0.0, I need to change it to:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" />
<html>
<head>
</head>
<body>
<form name="f" action="" method="post">

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<table>
<tr><td>Username:</td>
<td>
<input type="text" value="username" />
</td></tr>

<tr><td>Password: </td>
<td>
<input type="password" value="password" />
</td></tr>


<tr><td colspan="2"><input type="submit" value="Submit" /></td></tr>
</table>
</form>
</body>
</html>

In other words, the following changes must be made:

  • "j_username" changed to "username"
  • "j_password" changed to "password"
  • "j_spring_security_check" changed to "<c:url value="/login" />" 
  • add in a line in the form for
    csrf: <input type="hidden" name="${_csrf.parameterName}" value="$_csrf.token}" />
Then in each of my jsp views, if any form post action, the following hidden field must be included:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />

Similarly, in spring security 3.2.6, i can logout using a <a> link like this:

<a href="j_spring_security_logout">Logout</a>

Now in sprig security 4.0.0, I need to do the following instead:

<form action="<c:url value="/logout" />" method="post">
 <input type="submit" value="Logout" />
 
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>

No comments:

Post a Comment