Migrating to Spring Security 4
Modify pom.xml as follows.
pom.xml
<properties> <spring.version>5.3.33</spring.version> <spring.security.version>5.8.10</spring.security.version> <jdk.version>11</jdk.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-3.2.1.min.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