zoukankan      html  css  js  c++  java
  • JavaWeb-SpringSecurity自定义登陆页面

      系列博文

      项目已上传至guthub  传送门

      JavaWeb-SpringSecurity初认识  传送门

      JavaWeb-SpringSecurity在数据库中查询登陆用户  传送门

      JavaWeb-SpringSecurity自定义登陆页面  传送门

      JavaWeb-SpringSecurity实现需求-判断请求是否以html结尾  传送门

      JavaWeb-SpringSecurity自定义登陆配置  传送门

      JavaWeb-SpringSecurity图片验证ImageCode  传送门

      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
  • 相关阅读:
    jvm垃圾回收机制
    java中transient关键字的含义
    com.alipay.sofa.rpc.core.exception.SofaRouteException: RPC-02306: 没有获得服务[io.sofastack.balance.manage.facade.BalanceMngFacade:1.0:user77]的调用地址,请检查服务是否已经推送
    IDEA失效的解决办法
    多线程
    Java对象的创建过程
    注解(Annotation)
    面向对象思想
    IDEA--java版本修改(jdk1.8改成jdk1.7)
    HttpClient
  • 原文地址:https://www.cnblogs.com/1138720556Gary/p/11747420.html
Copyright © 2011-2022 走看看