I’m upgrading an application from Spring Boot 2.7 to Spring Boot 3 which includes updating to Spring Security 6.
We have the following properties set:
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
We use JSPs as a template language, where the controller returns the view file name e.g.
@RequestMapping("/")
public String home() {
return "home";
}
This will render the JSP page /WEB-INF/view/home.jsp
The security config is e.g.
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain config(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((auth) -> auth
.requestMatchers("/").permitAll()
.anyRequest().authenticated()
);
}
Since upgrading, visiting localhost/
redirects the browser to localhost/WEB-INF/view/home.jsp
and this returns a 403 because access to that page isn’t permitted.
If I allow access to this with .requestMatchers("/", "/WEB-INF/**").permitAll()
it works OK (i.e. stays on /
and renders the JSP page) but this seems like a bad idea, and an unnecessary step.
With debug logging on, Spring logs the following:
DEBUG [requestURL=/] o.s.security.web.FilterChainProxy : Securing GET /
DEBUG [requestURL=/] o.s.security.web.FilterChainProxy : Secured GET /
DEBUG [requestURL=/] o.s.security.web.FilterChainProxy : Securing GET /WEB-INF/view/home.jsp
DEBUG [requestURL=/] o.s.security.web.FilterChainProxy : Secured GET /WEB-INF/view/home.jsp
I cant’ see anything in Spring Security migration guide about this, does anyone know what is going on?
Update
I’ve isolated this into a clean example:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>jsptest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jsptest</name>
<packaging>war</packaging>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
</dependencies>
<build>
<finalName>app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Application.java
@SpringBootApplication
@Controller
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public SecurityFilterChain config(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/", "/WEB-INF/view/**").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
@RequestMapping("/")
public String home() {
return "home";
}
}
src/main/resources/application.properties:
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
src/main/webapp/WEB-INF/view/home.jsp:
hello
Something I’ve overlooked first as well.
In Spring Security 6, forwards and includes are part of the security filter by default.
See Permit FORWARD when using Spring MVC
Allowing forwards globally can be done through this additional line in security configuration.
.dispatcherTypeMatchers(DispatcherType.FORWARD).permitAll()
spring-boot
by default with executable asjar
and container oftomcat
orjetty
orundertow
does not supportjsp
. You must have some specific configurations made and made them work in spring-boot 2.7 so please share them as well as those need to be migrated as wellYour security configuration looks wrong. Which
init
method are you overriding? YOu should have a method that returns aSecurityFilter
from theHttpSecurity
method.@M.Deinum have fixed the config, apologies it was extracted for this post from a
AbstractHttpConfigurer
class.I still miss an
@EnableWebSecurity
… Nonetheless I doubt the security is your issue but not everything is in your question so it is hard to get to an answer.