我是 Spring Boot 新手,正在尝试创建一个简单的注册+登录。但是,每当我尝试使用 POST 请求提交数据时,请求就会被阻止 (403),并且我不会被重定向到成功页面。由于请求被阻止,当我尝试验证提交的输入时,这会导致空指针异常。
查看其他帖子,一个常见问题似乎是 csrf 保护,我明确禁用了它。其他帖子中的另一个常见问题是未授予正确的授权,我尝试使用
.permitAll().anyRequest().authenticated()
这样做。据我了解,我明确启用了“/register”的所有请求,因此我希望至少能够在控制器中的调试消息中获得凭据作为输出。
登记表;
<form th:action="@{register}" method="post" th:object="${registrationRequest}">
<div class="mb-3">
<label for="emailInput" class="form-label"></label>
<input th:field="*{email}" th:classappend="${#fields.hasErrors('email')} ? 'is-invalid'" type="email" class="form-control" id="emailInput" placeholder="Email">
</div>
<div class="mb-3">
<label for="usernameInput" class="form-label"></label>
<input th:field="*{name}" th:classappend="${#fields.hasErrors('name')} ? 'is-invalid'" type="text" class="form-control" id="usernameInput" placeholder="Username">
</div>
<div class="mb-3">
<label for="passwordInput" class="form-label"></label>
<input th:field="*{password}" th:classappend="${#fields.hasErrors('password')} ? 'is-invalid'" type="password" class="form-control" id="passwordInput" placeholder="Password">
</div>
<div class="mb-3">
<label for="passwordRepeatInput" class="form-label"></label>
<input th:field="*{passwordRepeat}" th:classappend="${#fields.hasErrors('passwordRepeat')} ? 'is-invalid'" type="password" class="form-control" id="passwordRepeatInput" placeholder="Password confirmation">
</div>
<button type="submit" class="btn btn-outline-dark btn-custom">Sign up!</button>
</form>
Controller中的路由;
@RequestMapping(value="register")
public String showRegisterPage(Model model) {
model.addAttribute("registrationRequest", new RegistrationRequest());
return "user/user-add";
}
@PostMapping(value="register")
public String processRegisterRequest(@ModelAttribute RegistrationRequest registrationRequest, BindingResult result) {
System.out.println("DEBUG: " + registrationRequest.getName() + registrationRequest.getEmail() + registrationRequest.getPassword());
System.out.println(result.getAllErrors());
userService.register(registrationRequest);
return "user/registration-success";
}
可能配置错误的SecurityFilterChain;
@Bean
public SecurityFilterChain securityFilterChain (HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers(
"/",
"/register",
"/login",
"/css/style.css")
.permitAll()
.anyRequest()
.authenticated())
.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable);
return http.build();
}
控制台错误输出;
2023-11-25T17:50:38.436+01:00 DEBUG 11889 --- [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2023-11-25T17:50:47.352+01:00 DEBUG 11889 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Securing POST /register
2023-11-25T17:50:47.354+01:00 DEBUG 11889 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Secured POST /register
DEBUG: nullnullnull
[]
DEBUG: nullnull
2023-11-25T17:50:47.360+01:00 DEBUG 11889 --- [nio-8080-exec-3] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2023-11-25T17:50:47.361+01:00 ERROR 11889 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException: Cannot invoke "String.length()" because "password" is null] with root cause
java.lang.NullPointerException: Cannot invoke "String.length()" because "password" is null
编辑
添加了RegistrationRequest类;
import lombok.*;
@Getter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class RegistrationRequest {
private String email;
private String name;
private String password;
private String passwordRepeat;
}
事实证明我的代码有2个问题;
.formLogin(Customizer.withDefaults())
添加到 SecurityFilterChain。 @Bean
public SecurityFilterChain securityFilterChain (HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers(
"/",
"/register",
"/login",
"/css/style.css")
.permitAll()
.anyRequest()
.authenticated())
.formLogin(Customizer.withDefaults())
.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable);
return http.build();
}
@Setter
注释,因此无法设置属性值。 import lombok.*;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class RegistrationRequest {
private String email;
private String name;
private String password;
private String passwordRepeat;
}