您好,我正在开发一个 Spring boot Web 应用程序,其中使用 Spring 安全性,对于视图,我使用 JSP 页面。当尝试访问使用 Permitall() 配置的页面(即主页和登录页面)时,我在浏览器上收到此错误,并且控制台上没有打印任何内容。因此,添加记录器后,我发现控制器函数被重复调用,下面是我的代码和控制台屏幕截图供参考,您可以让我知道我在这里做错了什么吗?
JSP 页面的Application.properties 文件
server.error.path=/error
spring.mvc.view.prefix: /WEB-INF/views/
spring.mvc.view.suffix: .jsp
页面控制器
@Controller
@RequestMapping(value = "/swadeshiBank/v1")
public class PageController {
public static final Logger logger = LogManager.getLogger(PageController.class);
private static final String loginPage = "login";
@GetMapping(value = "/")
public String homePage(){
logger.info("Request Came to home :");
return "home";
}
@GetMapping(value = "/login")
public String getLoginPage(){
logger.info("Request Came to login :");
return loginPage;
}
}
安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/", "/swadeshiBank/v1/", "/swadeshiBank/v1/login").permitAll() // Public pages
.requestMatchers("/swadeshiBank/v1/account-details").authenticated() // Authenticated users
.requestMatchers("/swadeshiBank/v1/admin").hasRole("ADMIN") // Admin users
.requestMatchers("/swadeshiBank/v1/management").hasRole("MANAGER") // Manager users
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/swadeshiBank/v1/login")
.loginProcessingUrl("/swadeshiBank/v1/login") // URL to submit the login form
.defaultSuccessUrl("/swadeshiBank/v1/account-details", true)
.permitAll()
)
.logout(logout -> logout
.logoutRequestMatcher(new AntPathRequestMatcher("/swadeshiBank/v1/logout"))
.logoutSuccessUrl("/swadeshiBank/v1/login?logout")
.invalidateHttpSession(true)
.permitAll()
);
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user")
.password("{noop}password")
.roles("USER")
.build());
manager.createUser(User.withUsername("admin")
.password("{noop}admin")
.roles("ADMIN")
.build());
manager.createUser(User.withUsername("manager")
.password("{noop}manager")
.roles("MANAGER")
.build());
return manager;
}
}
项目结构
你能帮我一下吗?另外,我打字时注意到的当前行为
http://localhost:8080/ 在浏览器中它会将我带到 http://localhost:8080/swadeshiBank/v1/login 但我希望登陆页面应该是 http://localhost:8080/swadeshiBank/v1 / 并且只有当我单击登录按钮时才会出现登录页面。
当您将 spring-security 记录器设置为
DEBUG
时,您可以看到 spring 尝试将 login.jsp
作为安全资源进行访问,这意味着它将文件锁定在其安全功能后面。
由于文件 url
/WEB-INF/views/login.jsp
无法被您定义的任何请求匹配器识别,因此仅允许经过身份验证的用户使用,因为这是您在 anyRequest()
lambda 函数中为 http.authorizeHttpRequests()
设置的内容。这仍然允许在没有身份验证的情况下访问 /login
url,但是对 login.jsp
文件的请求被 spring 阻止。每当 spring 阻止请求时,它就会将用户重定向到登录页面。由于您将 /login
url 重新路由到自定义端点,因此如果没有重定向数量的硬性限制,这将永远循环。
要解决您的问题,只需将
/WEB-INF/views/login.jsp
资源端点添加到具有 permitAll()
选项的请求匹配器中就足够了,如下所示:
// Class and stuff above
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/", "/swadeshiBank/v1/", "/swadeshiBank/v1/login", "/WEB-INF/views/login.jsp").permitAll() // Public pages
.requestMatchers("/swadeshiBank/v1/account-details").authenticated() // Authenticated users
.requestMatchers("/swadeshiBank/v1/admin").hasRole("ADMIN") // Admin users
.requestMatchers("/swadeshiBank/v1/management").hasRole("MANAGER") // Manager users
.anyRequest().authenticated()
)
// Your form-login-settings
// Your logout-settings
return http.build();
}
// Stuff below the method