Search code examples
springspring-securityspring-data-jpa

Get 302 on login submit


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.