Issue
When i log in i get a 302; I miss something. username and password are "post" parameters when i submit the login form. For now the root context is "localhost:port" but i'd like to redirect the successfull login to "localhost:port/mypage". I'm note sure the authentication works... i juste get a 302 and no error in the stacktrace.
I guess the formLogin is the problem... but i can't see any authorize token in the response. Do i need a ".successfullLogin" after formLogin() ?
Thank you. I lost a lot of time trying to fix and follow docs but i clearly not understand something important from the spring security basics !
My Controllers:
@Controller
public class TasklistController {
@Autowired
TasklistService tasklistservice;
@Autowired
TypeService typeService;
@RequestMapping("/tasklists")
public String tasklists(ModelMap modelMap){
modelMap.addAttribute("tasklists", tasklistservice.getAllTasklists());
modelMap.addAttribute("types", typeService.getAllTypeList());
modelMap.addAttribute("mode", "new");
return "showTasklists";
}
@RequestMapping("/addTaskList")
public String addTaskList(@Valid Tasklist tl,
BindingResult bindingResult, ModelMap modelMap){
if (bindingResult.hasErrors()) {
modelMap.addAttribute("errors", bindingResult.getAllErrors().get(0).getDefaultMessage());
modelMap.addAttribute("tasklists", tasklistservice.getAllTasklists());
modelMap.addAttribute("types", typeService.getAllTypeList());
return "showTasklists";
}
tl.setCreationDate(new Date());
tasklistservice.saveTasklist(tl);
return "showTasklists";
}
@Controller
public class SecurityController {
@GetMapping("/accessDenied")
public String error() {
return "accessDenied";
}
@GetMapping("/login")
public String login() {
return "login";
}
@GetMapping("/logout")
public String logout(HttpServletRequest request) throws ServletException {
request.logout();
return "redirect:/login";
}
}
and my Seucrity conf:
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
PasswordEncoder passwordEncoder = passwordEncoder ();
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests().antMatchers("tasklists").hasAnyRole("ADMIN, USER");
http.authorizeRequests().antMatchers("addTaskList").hasAnyRole("ADMIN, USER");
http.authorizeRequests().antMatchers("/login").permitAll();
http.authorizeRequests().anyRequest().authenticated();
http.formLogin().loginPage("/login");
// take "exceptionHandler "POST" not supported"
//http.exceptionHandling().accessDeniedPage("/accessDenied");
}
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers("/resources/**", "/static/**");
}
@Bean
public PasswordEncoder passwordEncoder () {
return new BCryptPasswordEncoder();
}
}
Here is the login template
{% block content %}
<div class="container mt-5">
<div class="col-md-6 offset-md-3">
<div class="card">
<div class="card-header">Connexion</div>
<div class="card-body">
<form action="/login" method="POST" name="login">
<div class="form-group">
<label class="control-label col-3" >Utilisateur :</label>
<input type="text" name="username" value="">
</div>
<div class="form-group">
<label class="control-label col-3" >Mot de passe :</label>
<input type="password" name="password" >
</div>
<button class="btn btn-primary float-end">Connexion</button>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
{% endblock %}
my USER table is "user_id", "username", "password", "enable". My user object is:
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long user_id;
private String username;
private Boolean enabled;
@JsonIgnore
private String password;
@JsonIgnore
@ManyToMany(cascade=CascadeType.ALL, fetch= FetchType.EAGER)
@JoinTable(name="user_role", joinColumns = @JoinColumn(name="user_id"), inverseJoinColumns = @JoinColumn(name="role_id"))
private List<Role> roles;
}
Solution
i did not really understand. I ended up having a redirection problem. It would not redirect to /tasklists but it got to work when i configure a mapping to "/". And now, it works, i guess, well... For now. But I can't say i know why.
Answered By - darkjp
Answer Checked By - Pedro (JavaFixing Volunteer)