Migrating to Spring Security 4
Modify pom.xml as follows.
pom.xml
<properties> <project.build.sourceEncoding<UTF-8</project.build.sourceEncoding> <maven.compiler.source<17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <spring.version>6.2.8</spring.version> <spring.security.version>6.5.1</spring.security.version> </properties>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
After building the project and rerunning Tomcat, go to the login page and try to log in. A blank screen is displayed, and there are no log messages about it. The cause of the blank screen is that the CSRF protection in Spring Security 4 is working. Spring Security 4 enables this feature by default. So, to migrate from Spring Security 3 to 4, you must include the CSRF token in all PATCH, POST, PUT and DELETE requests in your project.
Open the login.jsp file and add the following to the form:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
Try to log in again. This time you will get a 404 error that the server can not find /j_spring_security_check.
Attributes of form-login with default values changed in Spring Security 4
login-processing-url
/j_spring_security_check --> /login (of POST method)
username-parameter
j_username --> username
password-parameter
j_password --> password
authentication-failure-url
/login?error=1
Modify security.xml as follows.
security.xml
<form-login login-page="/users/login" authentication-failure-url="/users/login?error=1" default-target-url="/bbs/list?boardCd=chat&page=1" />
The default value of the login-page attribute is /login, and the default value of the authentication-failure-url attribute is /login?error=1. If you omit these attributes from the configuration file, Spring Security uses these default values.
To use a custom login page, you must specify the login-page and the authentication-failure-url attributes in the security configuration file, and then also add the following:
<http use-expressions="true"> <intercept-url pattern="/users/login" access="permitAll" />
The default value of use-expressions has been changed from false to true so that you can omit it like below.
<http> <intercept-url pattern="/users/login" access="permitAll" />
Modify login.jsp as follows.
/users/login.jsp
<c:if test="${param.error != null }">
<h2>Username/Password not corrrect</h2>
</c:if>
<c:url var="loginUrl" value="/login" />
<form action="${loginUrl }" method="post">
<p style="margin:0; padding: 0;">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</p>
<table>
<tr>
<td style="width: 200px;"><spring:message code="user.email" /></td>
<td style="width: 390px"><input type="text" name="username" style="width: 99%;" /></td>
</tr>
<tr>
<td><spring:message code="user.password" /></td>
<td><input type="password" name="password" style="width: 99%;" /></td>
</tr>
</table>
Build the project and rerun Tomcat. Try to log in and log out.
When you log out, you will see a blank screen again because the default value of the logout-url attribute is changed from /j_spring_security_logout to /logout of POST method.
Open the header.jsp file and modify the code of the logout button between <head> and </head> by referring to the following.
<input type="button" value="<spring:message code="user.logout" />" id="logout" />
Add the following at the bottom of header.jsp.
<form id="logoutForm" action="/logout" method="post" style="display:none">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
<script>
$(document).ready(function() {
$('#logout').click(function() {
$('#logoutForm').submit();
return false;
});
});
</script>
Add the following code to all JSP page that shows the screen.
<script type="text/javascript" src="/js/jquery.js"></script>
How to add CSRF token parameter when uploading files
When uploading attachments in a new post, you need to include the CSRF token in the query string even if you use Springform tags.
Open the write.jsp and modify.jsp files and delete the <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> in both files.
Modify the form's action attribute as shown below.
write.jsp
<sf:form action="write?${_csrf.parameterName}=${_csrf.token}" method="post" ...
modify.jsp
<sf:form action="modify?${_csrf.parameterName}=${_csrf.token}" method="post" ...
References
