JavaWeb-SpringSecurity自定义登陆页面

  系列博文:

  JavaWeb-SpringSecurity在数据库中查询登陆用户  博客园

  在static文件夹下添加一个login.html,作为自定义登陆页面

  

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<h1>Gary登陆页面</h1>
    <form action="/loginPage" method="post">
    
        用户名:
        <input type="text" name="username">
        <br>
        密码:
        <input type="password" name="password">
        <br>
        <input type="submit">
    
    </form>

</body>
</html>
login.html

  在SecurityConfig.java中的configure()方法中配置表单校验,添加一个自定义跳转的页面路径/login.html

    protected void configure(HttpSecurity http) throws Exception{
        //表单验证(身份认证)
        http.formLogin()
            //自定义登陆页面
            .loginPage("/login.html")
            .and()
            //请求授权
            .authorizeRequests()
            //所有请求都被拦截,跳转到(/login请求中)
            .anyRequest()
            //都需要我们身份认证
            .authenticated();
    }

  运行程序,发现页面进入死循环,提示错误页面包含的重定义过多了

  原因:用户想要进入我们自定义的登陆页面,需要SpringSecurity进行身份认证->但用户要通过SpringSecurity,就会跳转到我们自定义的登陆页面->用户进入我们自定义的登陆页面,就需要SpringSecurity进行身份认证...

  无限死循环了!!!

package com.Gary.GaryRESTful.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;


//Web应用安全适配器
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    //告诉SpringSecurity密码用什么加密的
    @Bean
    public PasswordEncoder passwordEncoder()
    {
        return new BCryptPasswordEncoder();
    }
    
    

    protected void configure(HttpSecurity http) throws Exception{
        //表单验证(身份认证)
        http.formLogin()
            //自定义登陆页面
            .loginPage("/login.html")
            .and()
            //请求授权
            .authorizeRequests()
            //所有请求都被拦截,跳转到(/login请求中)
            .anyRequest()
            //都需要我们身份认证
            .authenticated();
    }
    
}
SecurityConfig.java

  所以我们在配置SecurityConfig.java中的configure()时,对路径/login.html进行请求放行

protected void configure(HttpSecurity http) throws Exception{
        //表单验证(身份认证)
        http.formLogin()
            //自定义登陆页面
            .loginPage("/login.html")
            .and()
            //请求授权
            .authorizeRequests()
            //在访问我们的URL时,我们是不需要省份认证,可以立即访问
            .antMatchers("/login.html").permitAll()
            //所有请求都被拦截,跳转到(/login请求中)
            .anyRequest()
            //都需要我们身份认证
            .authenticated();
    }

  此时,我们再访问login.html时,发现就可以进入到我们自定义的登陆页面了

package com.Gary.GaryRESTful.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;


//Web应用安全适配器
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    //告诉SpringSecurity密码用什么加密的
    @Bean
    public PasswordEncoder passwordEncoder()
    {
        return new BCryptPasswordEncoder();
    }
    
    

    protected void configure(HttpSecurity http) throws Exception{
        //表单验证(身份认证)
        http.formLogin()
            //自定义登陆页面
            .loginPage("/login.html")
            .and()
            //请求授权
            .authorizeRequests()
            //在访问我们的URL时,我们是不需要省份认证,可以立即访问
            .antMatchers("/login.html").permitAll()
            //所有请求都被拦截,跳转到(/login请求中)
            .anyRequest()
            //都需要我们身份认证
            .authenticated();
    }
    
}
SecurityConfig.java

  此时,我们在自己的页面中输入数据库中账号密码,页面的拦截器都不会生效

  这是因为login.html中表单/loginPage请求路径拦截器不认识

  按住Ctrl+Shift+T,可以找到SpringSecurity拦截器中UsernamePasswordAuthenticationFilter的方法

public class UsernamePasswordAuthenticationFilter extends
        AbstractAuthenticationProcessingFilter {
    // ~ Static fields/initializers
    // =====================================================================================

    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";

    private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
    private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
    private boolean postOnly = true;

    // ~ Constructors
    // ===================================================================================================

    public UsernamePasswordAuthenticationFilter() {
        super(new AntPathRequestMatcher("/login", "POST"));
    }

  现在需要我们login.html中的表单发送请求访问SpringSecurity拦截器中的UsernamePasswordAuthenticationFilter()这个方法,处理用户登陆的请求

  (如果要使用UsernamePasswordAuthenticationFilter()这个方法处理用户登陆,一定需要在配置表单登陆时,添加一个csrf跨站请求伪造的防护)

    protected void configure(HttpSecurity http) throws Exception{
        //表单验证(身份认证)
        http.formLogin()
            //自定义登陆页面
            .loginPage("/login.html")
            //如果URL为loginPage,则用SpringSecurity中自带的过滤器去处理该请求
            .loginProcessingUrl("/loginPage")
            .and()
            //请求授权
            .authorizeRequests()
            //在访问我们的URL时,我们是不需要省份认证,可以立即访问
            .antMatchers("/login.html").permitAll()
            //所有请求都被拦截,跳转到(/login请求中)
            .anyRequest()
            //都需要我们身份认证
            .authenticated()
            //SpringSecurity保护机制
            .and().csrf().disable();
    }

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<h1>Gary登陆页面</h1>
    <form action="/loginPage" method="post">
    
        用户名:
        <input type="text" name="username">
        <br>
        密码:
        <input type="password" name="password">
        <br>
        <input type="submit">
    
    </form>

</body>
</html>
login.html
package com.Gary.GaryRESTful.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;


//Web应用安全适配器
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    //告诉SpringSecurity密码用什么加密的
    @Bean
    public PasswordEncoder passwordEncoder()
    {
        return new BCryptPasswordEncoder();
    }
    
    

    protected void configure(HttpSecurity http) throws Exception{
        //表单验证(身份认证)
        http.formLogin()
            //自定义登陆页面
            .loginPage("/login.html")
            //如果URL为loginPage,则用SpringSecurity中自带的过滤器去处理该请求
            .loginProcessingUrl("/loginPage")
            .and()
            //请求授权
            .authorizeRequests()
            //在访问我们的URL时,我们是不需要省份认证,可以立即访问
            .antMatchers("/login.html").permitAll()
            //所有请求都被拦截,跳转到(/login请求中)
            .anyRequest()
            //都需要我们身份认证
            .authenticated()
            //SpringSecurity保护机制
            .and().csrf().disable();
    }
    
}
SecurityConfig.java

猜你喜欢

转载自www.cnblogs.com/1138720556Gary/p/11747420.html
今日推荐