I am learning spring boot and write a register form, but when I run it in idea and submit the form, the browser occurs
There was an unexpected error (type=Forbidden, status=403). Forbidden
I create the project by using spring initializr in idea, choose web+jpa+h2+thymeleaf. I defined an Entity called Worker and set error messages in ValidationMessages.properties, here is the Worker entity
@Entity
public class Worker implements UserDetails {
private static final long serialversionUID = 1L;
@Id
@NotNull
@Size(min = 5, max = 16, message = "{username.size}")
private String username;
@NotNull
@Size(min = 2, max = 30, message = "{firstName.size}")
private String firstname;
@NotNull
@Size(min = 2, max = 30, message = "{lastName.size")
private String lastname;
@NotNull
@Size(min = 5, max = 25,message = "{password.size}")
private String password;
@NotNull
@Size(min = 2, max = 30, message = "{profession,size}")
private String profession;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
//UserDetails methods
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("WORKER"));
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
and WorkersRepository
public interface WorkersRepository extends JpaRepository<Worker, String> {
Worker findByUsername(String username);
}
I have added spring security, and wrote the config:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private WorkersRepository workersRepository;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/submit").access("hasRole('WORKER')")
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
.and()
.logout()
.logoutSuccessUrl("/")
.and()
.rememberMe()
.tokenValiditySeconds(4838400)
.key("workerKey");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return workersRepository.findByUsername(username);
}
});
}
}
If the register input occurs error, the controller returns the registerForm.html to ask user to input again correctly. If the register has no error, the controller redirects to "/", a simple welcome.html. But whether the input is correct or not, I always get the error 403. When I inputhttp://localhost:8080/
, I can get the welcome.html,which is a simple page with "welcome!" words. My controller is
private WorkersRepository workersRepository;
@Autowired
public WorkingHoursController(
WorkersRepository workersRepository) {
this.workersRepository = workersRepository;
}
@RequestMapping(method = RequestMethod.GET)
public String welcomePage() {
return "welcome";
}
@RequestMapping(value = "/register", method = RequestMethod.GET)
public String showRegistrationForm(Model model) {
model.addAttribute(new Worker());
return "registerForm";
}
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String registrationProcessing(@Valid Worker worker, Errors errors, RedirectAttributes model) {
if(errors.hasErrors()) {
return "registerForm";
}
workersRepository.save(worker);
model.addAttribute("username", worker.getUsername());
model.addFlashAttribute("worker", worker);
return "redirect:/";
}
...
I wrote the registerForm.html using thymeleaf and add error validations. My registerForm.html is
<form class="form-signin" method="post" th:object="${worker}">
<div class="errors" th:if="${#fields.hasErrors('*')}">
<ul>
<li th:each="err : ${#fields.errors('*')}"
th:text="${err}">Input is in correct.</li>
</ul>
</div>
<img class="mb-4" src="https://getbootstrap.com/assets/brand/bootstrap-solid.svg" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal">Please register</h1>
<!-- input username -->
<label for="inputUsername" th:class="${#fields.hasErrors('username')}? 'error'">Username</label>
<input type="text" id="inputUsername" th:field="*{username}" th:class="${#fields.hasErrors('username')}? 'error form-control':'form-control'" placeholder="Username">
...
<!-- input password -->
<label for="inputPassword" th:class="${#fields.hasErrors('password')}? 'error'">Password</label>
<input type="password" id="inputPassword" th:field="*{password}" th:class="${#fields.hasErrors('password')}? 'error form-control':'form-control'" placeholder="Password">
<div class="checkbox mb-3">
<label>
<input type="checkbox" id="remember-me" name="remember-me"> Remember me
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Register</button>
Before I add validations in thymeleaf and add spring security, everything seems to work properly.
You did not put any action inside form tag. Perhaps that's why you are getting error. Put action inside form tag like this one
<form class="form-signin" action="#" th:action="@{/register}" method="post" th:object="${worker}">
Please check once whether role should be "WORKER" or "ROLE_WORKER" according to your Spring Security JAR version. Also disable the CSRF in your application, and set global CORS config to accept all requests.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With