02-SpringSecurity自定义登录页面、成功或失败处理逻辑


首先介绍一下spring-security的配置应该怎么写:

重写WebSecurityConfigurerAdapter类中的方法,最基本的是重写configure(HttpSecurity httpSecurity)方法。(具体代码往下看)

第一步,自定义一个登录页面:

package com.eknown.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * @author eknown
 * @version 1.0
 * @since 2019/5/29 14:44
 */
@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.formLogin() // 表单验证方式
                //.httpBasic() // http弹框验证-alert形式
                .loginPage("/login.html")
                .loginProcessingUrl("/login")
                .and()
                .authorizeRequests() // 授权配置
                .antMatchers("/login.html").permitAll() // login界面全部授权
                .anyRequest() // 对所有请求生效
                .authenticated(); // 都需要认证
    }
}

这里定义了一个login.html页面,我放在了resources/resources文件夹下:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页title>
head>
<body>
    <form class="login-form" action="/login" method="post">
        <div class="form">
            <h3>账户登录h3>
            <input type="text" placeholder="用户名" name="username" required="required">
            <input type="password" placeholder="密码" name="password" required="required">
            <button type="submit">登录button>
        div>
    form>
body>
<style>
  
style>
html>

注意这里的用户名和密码输入框的name值必须是usernamepassword,这是spring-security默认的。

下面我们配置一下登录页面和登录请求:

package com.eknown.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * @author eknown
 * @version 1.0
 * @since 2019/5/29 14:44
 */
@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.formLogin() // 表单验证方式
                //.httpBasic() // http弹框验证-alert形式
                .loginPage("/login.html")
                .loginProcessingUrl("/login")
                .defaultSuccessUrl("/").permitAll()
                .and()
                .authorizeRequests() // 授权配置
                .antMatchers("/login.html").permitAll() // login界面全部授权
                .anyRequest() // 对所有请求生效
                .authenticated() //; // 都需要认证
                .and().csrf().disable(); // 关闭csrf,否则会导致登录不成功
    }
}

下面我们添加一个登录失败处理配置:

package com.eknown.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author zfh
 * @version 1.0
 * @since 2019/5/31 9:44
 */
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Autowired
    private ObjectMapper mapper;

    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        httpServletResponse.setContentType("application/json;charset=utf-8");
        httpServletResponse.getWriter().write(mapper.writeValueAsString(e.getMessage()));
    }
}

然后将这个实现了AuthenticationFailureHandler接口的类应用到配置上:

@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyAuthenticationFailureHandler failureHandler;

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.formLogin() // 表单验证方式
                //.httpBasic() // http弹框验证-alert形式
                .loginPage("/login.html")
                .loginProcessingUrl("/login")
                .defaultSuccessUrl("/").permitAll()
                .failureHandler(failureHandler)
                .and()
                .authorizeRequests() // 授权配置
                .antMatchers("/login.html").permitAll() // login界面全部授权
                .anyRequest() // 对所有请求生效
                .authenticated() //; // 都需要认证
                .and().csrf().disable(); //
    }
}

关于登录成功后的逻辑,除了自定义的defaultSuccessUrl外,也可以通过实现AuthenticationSuccessHandler接口中的onAuthenticationSuccess方法,然后像在SecurityConfig类中添加.successHandler(xxx)即可。

启动项目,访问,可以看到自动重定向到了登录页面:

02-SpringSecurity自定义登录页面、成功或失败处理逻辑_第1张图片

注:本处登录页copy自mrbird

随意输入用户名密码,点击登录,看到如下错误提示:
02-SpringSecurity自定义登录页面、成功或失败处理逻辑_第2张图片

输入正确的用户名(user)和密码(默认生成的,在控制台可以看到),点击登录,看到:

02-SpringSecurity自定义登录页面、成功或失败处理逻辑_第3张图片


这一讲,我们便构建了一个简单的、自定义的登录逻辑。但是,这样的登录逻辑对于项目是不够的,仅仅只能作为一个demo。下一讲,将实现基于数据库user表的用户登录功能。

你可能感兴趣的:(security)