6

I want to have more control over the logging in and out, via custom controller and login page.

My SecurityConfiguration code currently looks like this:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private SpringDataJpaUserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .userDetailsService(this.userDetailsService)
                .passwordEncoder(Manager.PASSWORD_ENCODER);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
            .antMatchers("/resources/**", "/built/**", "/main.css", "/login.css").permitAll() 
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/login")
            .loginProcessingUrl("/loginSecure")
            .defaultSuccessUrl("/index", true)
            .permitAll()
            .usernameParameter("username").passwordParameter("password")
            .and()
        .csrf().disable()
        .logout()                                    
            .permitAll();
    }

}

My login config in my Controller:

@RequestMapping(value = "/login")
public String login() {
    return "login";
}

My loginSecure mapping in my controller:

@RequestMapping(value="/loginSecure", method = RequestMethod.POST)
    public String login(@RequestAttribute("username") String userName, @RequestAttribute("password")  String password) {

        //does the authentication
        final Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        userName,
                        password
                )
        );
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return "index";
    }

My login.html:

<form class="login100-form validate-form" action="/loginSecure" method="post">
                    <span class="login100-form-title p-b-26">
                        Welcome
                    </span>
                    <span class="login100-form-title p-b-48">
                        <i class="zmdi zmdi-font"></i>
                    </span>     
                        <div class="wrap-input100 validate-input" data-validate = "Valid email is: a@b.c">
                            <input class="input100" type="text" id="username" name="username"/>
                            <span class="focus-input100" data-placeholder="Email/Username"></span>
                        </div>

                        <div class="wrap-input100 validate-input" data-validate="Enter password">
                            <span class="btn-show-pass">
                                <i class="zmdi zmdi-eye"></i>
                            </span>
                            <input class="input100" type="password" id="password" name="password"/>
                            <span class="focus-input100" data-placeholder="Password"></span>
                        </div>

                        <div class="container-login100-form-btn">
                            <div class="wrap-login100-form-btn">
                                <div class="login100-form-bgbtn"></div>
                                    <button class="login100-form-btn">
                                        Login
                                    </button>
                            </div>
                        </div>
                    </form> 

When i submit the form, in chrome dev tools it submits as loginSecure? with url encoded but it just redirects back to the login.html again. chrome web tools network

Edit: Removed the extra form from login.html and added csfr().disable to securityConfiguration. Added loginProcessUrl to httpSecurity and this fixed it. Above code works.

pronane
  • 248
  • 1
  • 5
  • 10

2 Answers2

2

If you create a custom login html and a custom authenticator then you need to add this to the HttpSecurity config -> .loginProcessingUrl("/loginSecure")

Good example here -> https://www.boraji.com/spring-security-4-custom-login-from-example

pronane
  • 248
  • 1
  • 5
  • 10
0

From what you wrote I guess that the problem is that after clicking "Login" your application is hit by two request.

I think that problem is that your login page has two forms one inside another. So when you click "Login" both forms sends their requests. You can verify that in Chrome Developer Tools.

As you can read here HTML doesn't allow nested forms Is it valid to have a html form inside another html form?

Paweł Adamski
  • 3,285
  • 2
  • 28
  • 48
  • Yes that was a mistake! I had used an existing template and looked at the code and thought is there another form but couldn't see it and didn't search. Needed to step back. Thanks for the spot! – pronane Feb 26 '18 at 19:52