春季启动百里香叶自定义登录未正确重定向



我有一个Spring Boot Thymeleaf项目,我试图在下面引入一个自定义登录页面https://www.baeldung.com/spring-security-login。当我浏览到应用程序根目录时,它重定向到http://localhost:8080/login.html,但不是登录表单,我得到错误:

页面没有正确重定向。Firefox已经检测到服务器正在以某种方式重定向此地址的请求从未完成。

在添加登录自定义之前,我有一个通用的登录弹出窗口。这是我在自定义登录中添加的东西。我的WebSecurityConfig:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/login*", "/", "/search", "/browse", "/recipes/**", "/tags/**", "/edit/**", "/delete/**")
.hasRole("ADMIN")
.antMatchers("/login*", "/", "/search", "/browse", "/recipes/**", "/tags/**")
.hasRole("USER")
.anyRequest()
.authenticated()
.and()
.formLogin().loginPage("/login.html")
.defaultSuccessUrl("/", true)
.failureUrl("/login.html?error=true");
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Bean
public InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.withUsername("foote").password(passwordEncoder().encode("userpassword")).roles("USER")
.build();
UserDetails admin = User.withUsername("admin").password(passwordEncoder().encode("adminpassword"))
.roles("USER", "ADMIN").build();
return new InMemoryUserDetailsManager(user, admin);
}
}

我的login.html(根据文章):

<html>
<head></head>
<body>
<h1>Login</h1>
<form name='f' action="login" method='POST'>
<table>
<tr>
<td>User:</td>
<td><input type='text' name='username' value=''></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='password' name='password' /></td>
</tr>
<tr>
<td><input name="submit" type="submit" value="submit" /></td>
</tr>
</table>
</form>
</body>
</html>

应用程序日志"logging.level.org.springframework.security=DEBUG"在application.properties:

2022-11-19T10:07:06.116 [http-nio-8080-exec-1] [DEBUG] [o.s.security.web.FilterChainProxy] Securing GET /
2022-11-19T10:07:06.119 [http-nio-8080-exec-1] [DEBUG] [o.s.s.w.c.SecurityContextPersistenceFilter] Set SecurityContextHolder to empty SecurityContext
2022-11-19T10:07:06.121 [http-nio-8080-exec-1] [DEBUG] [o.s.s.w.a.AnonymousAuthenticationFilter] Set SecurityContextHolder to anonymous SecurityContext
2022-11-19T10:07:06.127 [http-nio-8080-exec-1] [DEBUG] [o.s.s.w.a.i.FilterSecurityInterceptor] Failed to authorize filter invocation [GET /] with attributes [hasRole('ROLE_USER')]
2022-11-19T10:07:06.135 [http-nio-8080-exec-1] [DEBUG] [o.s.s.w.s.HttpSessionRequestCache] Saved request http://localhost:8080/ to session
2022-11-19T10:07:06.135 [http-nio-8080-exec-1] [DEBUG] [o.s.s.web.DefaultRedirectStrategy] Redirecting to http://localhost:8080/login.html
2022-11-19T10:07:06.136 [http-nio-8080-exec-1] [DEBUG] [o.s.s.w.c.HttpSessionSecurityContextRepository] Did not store empty SecurityContext
2022-11-19T10:07:06.137 [http-nio-8080-exec-1] [DEBUG] [o.s.s.w.c.HttpSessionSecurityContextRepository] Did not store empty SecurityContext
2022-11-19T10:07:06.137 [http-nio-8080-exec-1] [DEBUG] [o.s.s.w.c.SecurityContextPersistenceFilter] Cleared SecurityContextHolder to complete request
2022-11-19T10:07:06.169 [http-nio-8080-exec-2] [DEBUG] [o.s.security.web.FilterChainProxy] Securing GET /login.html
2022-11-19T10:07:06.169 [http-nio-8080-exec-2] [DEBUG] [o.s.s.w.c.SecurityContextPersistenceFilter] Set SecurityContextHolder to empty SecurityContext
2022-11-19T10:07:06.170 [http-nio-8080-exec-2] [DEBUG] [o.s.s.w.a.AnonymousAuthenticationFilter] Set SecurityContextHolder to anonymous SecurityContext
2022-11-19T10:07:06.170 [http-nio-8080-exec-2] [DEBUG] [o.s.s.w.a.i.FilterSecurityInterceptor] Failed to authorize filter invocation [GET /login.html] with attributes [hasRole('ROLE_USER')]
2022-11-19T10:07:06.171 [http-nio-8080-exec-2] [DEBUG] [o.s.s.w.s.HttpSessionRequestCache] Saved request http://localhost:8080/login.html to session
2022-11-19T10:07:06.171 [http-nio-8080-exec-2] [DEBUG] [o.s.s.web.DefaultRedirectStrategy] Redirecting to http://localhost:8080/login.html
2022-11-19T10:07:06.171 [http-nio-8080-exec-2] [DEBUG] [o.s.s.w.c.HttpSessionSecurityContextRepository] Did not store empty SecurityContext
2022-11-19T10:07:06.171 [http-nio-8080-exec-2] [DEBUG] [o.s.s.w.c.HttpSessionSecurityContextRepository] Did not store empty SecurityContext
2022-11-19T10:07:06.171 [http-nio-8080-exec-2] [DEBUG] [o.s.s.w.c.SecurityContextPersistenceFilter] Cleared SecurityContextHolder to complete request
2022-11-19T10:07:06.189 [http-nio-8080-exec-3] [DEBUG] [o.s.security.web.FilterChainProxy] Securing GET /login.html
2022-11-19T10:07:06.190 [http-nio-8080-exec-3] [DEBUG] [o.s.s.w.c.SecurityContextPersistenceFilter] Set SecurityContextHolder to empty SecurityContext
...

最后一个动作,保护/login.html,在错误之前重复了十几次,我认为是循环的。

我错过了什么或做错了什么?

更新:未收到任何响应;还有什么我可以补充的吗?

所以我想我已经得到了这个工作。原来是少了一些东西。

在WebSecurityConfig中,我说使用自定义登录页面,但我没有提供对它的访问。所以我在声明loginPage之后添加了permitAll()。我在登录之前提供了对所需资源的访问(第一个antMatcher)。我在角色的antMatchers中也遗漏了一些模式。最终结果:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig {
/**
* Configures HTTP security.
*
* @param http {@link HttpSecurity}
* @return {@link SecurityFilterChain}
* @throws Exception when the internet falls over.
*/
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/login*", "/resources/**", "/error")
.permitAll()
.antMatchers("/", "/login*", "/error", "/search", "/browse", "/recipes/**", "/tags/**",
"/resources/**", "/add", "/create", "/uploadImage", "/edit/**", "/delete/**")
.hasRole("ADMIN")
.antMatchers("/", "/login*", "/error", "/search", "/browse", "/recipes/**", "/tags/**",
"/resources/**")
.hasRole("USER")
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.defaultSuccessUrl("/", true)
.failureUrl("/login?error=true");
return http.build();
}
/**
* Use password encoding.
*
* @return {@link PasswordEncoder}
*/
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
/**
* Username and password and roles.
*
* @return {@link InMemoryUserDetailsManager}
*/
@Bean
public InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.withUsername("user").password(passwordEncoder().encode("password")).roles("USER")
.build();
UserDetails admin = User.withUsername("admin").password(passwordEncoder().encode("password"))
.roles("USER", "ADMIN").build();
return new InMemoryUserDetailsManager(user, admin);
}
/**
* Specify resources to allow without credentials.
*
* @return {@link WebSecurityCustomizer}
*/
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedPercent(true);
return web -> web.httpFirewall(firewall)
.ignoring()
.antMatchers("/styles/**", "/js/**", "/images/**", "/fonts/**", "/resources/**");
}
}

最新更新