简体   繁体   中英

spring boot and spring security custom login page and controller

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网络工具网络

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.

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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM