使用jsp迁移到Spring security 6后出现ERR_TOO_MANY_REDIRECTS

问题描述 投票:0回答:1

我正在将我的项目迁移到 Spring boot 3。它配置了 jsp 页面。问题是当使用 Spring security 6 运行时,页面不再加载,浏览器上出现错误 ERR_TOO_MANY_REDIRECTS

我得到了很多调试日志,但都是一样的:

2024-06-27T10:24:47.982+02:00 DEBUG 55771 --- [jsp] [0.1-8080-exec-2] o.s.w.servlet.view.InternalResourceView  : View name 'login', model {}
2024-06-27T10:24:47.983+02:00 DEBUG 55771 --- [jsp] [0.1-8080-exec-2] o.s.w.servlet.view.InternalResourceView  : Forwarding to [/WEB-INF/jsp/login.jsp]
2024-06-27T10:24:47.984+02:00 DEBUG 55771 --- [jsp] [0.1-8080-exec-4] o.s.w.servlet.view.InternalResourceView  : View name 'login', model {}
2024-06-27T10:24:47.984+02:00 DEBUG 55771 --- [jsp] [0.1-8080-exec-4] o.s.w.servlet.view.InternalResourceView  : Forwarding to [/WEB-INF/jsp/login.jsp]

我的安全配置文件 src/main/java/org/example/jsp/WebSecurityConfig.java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http

                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/login").permitAll()
                        .anyRequest().authenticated()
                )
                .formLogin(form -> form.loginPage("/login")
                                .loginProcessingUrl("/login")
                        .permitAll()
                )
                .logout(logout -> logout
                        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                        .logoutSuccessUrl("/login")
                        .permitAll()
                );
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user =
            User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(user);
    }
}

src/main/webapp/WEB-INF/jsp/login.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
<h1>Login</h1>
<form action="${pageContext.request.contextPath}/login" method="post">
    <div>
        <label for="username">Username:</label>
        <input type="text" id="username" name="username"/>
    </div>
    <div>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password"/>
    </div>
    <div>
        <button type="submit">Login</button>
    </div>
    <c:if test="${param.error != null}">
        <div>Invalid username or password.</div>
    </c:if>
</form>
</body>
</html>

src/main/java/org/example/jsp/JspController.java

@Controller
public class JspController {

    @GetMapping("/login")
    public String getLogin() {
        return "login";
    }

    @GetMapping("/home")
    public String home() {
        return "home";
    }
}

以及 pox.xml 中的依赖项

<properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <!-- Spring Boot dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
        </dependency>

        <!-- JSP dependencies -->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jakarta.servlet.jsp</groupId>
            <artifactId>jakarta.servlet.jsp-api</artifactId>
            <version>3.0.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>jakarta.servlet.jsp.jstl</artifactId>
<!--            <version>2.0.0</version>-->
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- Server dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- Test dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

我使用过Spring boot 3.2.7

应用程序属性(src/main/resources/application.properties)文件包含

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

还尝试添加

src/main/java/org/example/jsp/WebMvcConfig.java:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/jsp/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}

我不明白我做错了什么。请指导我解决这个问题,非常感谢。 :)

更新:

以下是日志:

2024-06-28T14:02:41.048+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.s.security.web.FilterChainProxy        : Securing GET /login
2024-06-28T14:02:41.048+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.s.security.web.FilterChainProxy        : Secured GET /login
2024-06-28T14:02:41.048+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.s.web.servlet.DispatcherServlet        : GET "/login", parameters={}
2024-06-28T14:02:41.048+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.example.jsp.JspController#getLogin()
2024-06-28T14:02:41.048+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, */*;q=0.8, application/signed-exchange;v=b3;q=0.7]
2024-06-28T14:02:41.048+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.s.w.servlet.view.InternalResourceView  : View name 'login', model {}
2024-06-28T14:02:41.048+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.s.w.servlet.view.InternalResourceView  : Forwarding to [/WEB-INF/jsp/login.jsp]
2024-06-28T14:02:41.048+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.s.security.web.FilterChainProxy        : Securing GET /WEB-INF/jsp/login.jsp
2024-06-28T14:02:41.048+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2024-06-28T14:02:41.049+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.s.s.w.s.HttpSessionRequestCache        : Saved request http://localhost:8080/WEB-INF/jsp/login.jsp?continue to session
2024-06-28T14:02:41.049+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.s.s.web.DefaultRedirectStrategy        : Redirecting to http://localhost:8080/login
2024-06-28T14:02:41.049+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.a.c.c.C.[.[localhost].[/].[jsp]        : The response class [class org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterResponse] could not be unwraped to the Catalina response class and will be closed immediately after the forward
2024-06-28T14:02:41.049+02:00 DEBUG 77220 --- [jsp] [.1-8080-exec-10] o.s.web.servlet.DispatcherServlet        : Completed 302 FOUND

然后为了解决重定向问题,我在安全配置的 PermitAll 中添加了

WEB-INF

.requestMatchers("/login", "/error", "/webjars/**", "/css/**", "/WEB-INF/**").permitAll()

现在的新错误是

2024-06-28T14:04:54.841+02:00 DEBUG 77243 --- [jsp] [0.1-8080-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /login
2024-06-28T14:04:54.848+02:00 DEBUG 77243 --- [jsp] [0.1-8080-exec-1] o.s.security.web.FilterChainProxy        : Secured GET /login
2024-06-28T14:04:54.849+02:00 DEBUG 77243 --- [jsp] [0.1-8080-exec-1] o.s.web.servlet.DispatcherServlet        : GET "/login", parameters={}
2024-06-28T14:04:54.850+02:00 DEBUG 77243 --- [jsp] [0.1-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.example.jsp.JspController#getLogin()
2024-06-28T14:04:54.857+02:00 DEBUG 77243 --- [jsp] [0.1-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, */*;q=0.8, application/signed-exchange;v=b3;q=0.7]
2024-06-28T14:04:54.857+02:00 DEBUG 77243 --- [jsp] [0.1-8080-exec-1] o.s.w.servlet.view.InternalResourceView  : View name 'login', model {}
2024-06-28T14:04:54.858+02:00 DEBUG 77243 --- [jsp] [0.1-8080-exec-1] o.s.w.servlet.view.InternalResourceView  : Forwarding to [/WEB-INF/jsp/login.jsp]
2024-06-28T14:04:54.860+02:00 DEBUG 77243 --- [jsp] [0.1-8080-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /WEB-INF/jsp/login.jsp
2024-06-28T14:04:54.862+02:00 DEBUG 77243 --- [jsp] [0.1-8080-exec-1] o.s.security.web.FilterChainProxy        : Secured GET /WEB-INF/jsp/login.jsp
2024-06-28T14:04:54.906+02:00 ERROR 77243 --- [jsp] [0.1-8080-exec-1] o.a.c.c.C.[.[localhost].[/].[jsp]        : Servlet.service() for servlet [jsp] threw exception

java.lang.ClassNotFoundException: jakarta.servlet.jsp.jstl.core.ConditionalTagSupport
.
.
.
2024-06-28T14:04:54.908+02:00 DEBUG 77243 --- [jsp] [0.1-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Error rendering view [org.springframework.web.servlet.view.InternalResourceView: name 'login'; URL [/WEB-INF/jsp/login.jsp]]
spring spring-mvc spring-security
1个回答
0
投票

我的JSP页面也经过了身份验证,所以我添加了permitAll,帮助我解决了问题,同时还暂时禁用了csrf

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers( "/webjars/**", "/WEB-INF/**").permitAll()
                        .anyRequest().authenticated()
                )
                .formLogin(formLogin -> formLogin
                        .loginPage("/login")
                        .failureUrl("/login?error=true")
                        .permitAll()
                )
                .logout(logout -> logout
                        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                        .logoutSuccessUrl("/login")
                        .permitAll()
                )
                .csrf(AbstractHttpConfigurer::disable);

        return http.build();
    }

此外,我使用了错误的依赖关系,

<dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>jstl</artifactId>
     <version>1.2</version>
</dependency>

相反应该使用

<dependency>
    <groupId>jakarta.servlet.jsp.jstl</groupId>
    <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
    <version>3.0.0</version>
</dependency>
© www.soinside.com 2019 - 2024. All rights reserved.