Home > Enterprise >  Permit page, if login form custom form was successful
Permit page, if login form custom form was successful

Time:11-02

I am very new to Spring Security. In Angular I have a custom form that sends a post to this controller:

@RestController
public class LoginController {
    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestBody User user) {
        if (user.getUsername().equals("linda") && user.getPassword().equals("pass")) {
            return ResponseEntity.ok("Access granted");
        }
        return ResponseEntity.badRequest().body("Access denied");
    }
}

If the login was successful, the user should have access to the page /welcome, otherwise this page should be forbidden.

This is what I have tried:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class Config {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(10);
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/login").permitAll()
                .antMatchers("/welcome").hasAnyRole("ADMIN")
                .anyRequest()
                .authenticated()
                .and()
                .formLogin(form -> form.loginPage("/login").permitAll());
        return http.build();
    }

    @Bean
    public InMemoryUserDetailsManager userDetailsManager() {
        var linda = User.builder()
                .username("linda")
                .password(passwordEncoder().encode("pass"))
                .roles("ADMIN")
                .build();
        return new InMemoryUserDetailsManager(linda);
    }
}

When I call /login, I get the status 405 - Method Not Allowed.

enter image description here

Probably I am doing everything wrong. How can this be done correctly?

CodePudding user response:

There's 2 things that should be updated in your login endpoint :

  1. @PostMapping("login") should be @PostMapping("/login")

  2. You should either define a class containing username and password as fields and update your endpoint parameters to the below :

    public ResponseEntity<String> login(@RequestBody CustomUser customUser) {

    or you could use it as follow : public ResponseEntity<String> login(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password) {

UPDATE :

Following your update, i've resimulate your scenario and the configuration is wrong as you've already mentioned.

Configuration should be as follow and there's no need to create a login endpoint :

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(10);
}

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests().antMatchers("/login", "/loginFailed").permitAll()
            .antMatchers("/welcome").hasAnyRole("ADMIN").anyRequest()
            .authenticated().and()
            .formLogin(form -> form.loginPage("/login")
                    .usernameParameter("username")
                    .passwordParameter("password")
                    .defaultSuccessUrl("/welcome")
                    .failureUrl("/loginFailed"));
    return http.build();
}

@Bean
public InMemoryUserDetailsManager userDetailsManager() {
    UserDetails linda = User.builder().username("linda")
            .password(passwordEncoder().encode("pass")).roles("ADMIN")
            .build();
    return new InMemoryUserDetailsManager(linda);
}

However username and password should be submitted in the query param as per the default configuration in "UsernamePasswordAuthenticationFilter". You could change the default behavior by implementing your Custom UsernamePasswordAuthenticationFilter. (Check enter image description here

Endpoints :

@GetMapping("/welcome")
public ResponseEntity<String> welcome(Authentication authentication) {
    return ResponseEntity.ok("Weclome ["   authentication.getName()   "]");
}

@GetMapping("/loginFailed")
public ResponseEntity<String> login() {
    return ResponseEntity.ok("Failed to login");
}

Hope it helps

  • Related