3.spring-security自定义表单登录页面

spring-security自定义表单登录页面

在config包下编写SecurityConfiguration配置类

package com.po.config;

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


@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    /**
     * http请求方法
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /** http.httpBasic() //开启httpBasic认证
         .and().authorizeRequests().anyRequest().authenticated(); //所有请求都需要认证之后访问
         */
        http.formLogin().loginPage("/login.html")//开启表单认证
                .and().authorizeRequests() //放行登录页面
                .anyRequest().authenticated();
    }
}

注意:WebSecurityConfigurerAdapter 抽象类有三个configure方法,分别对应的是 身份安全管理器, 忽略静态资源, http请求方法;

点击运行发现如下问题

因为设置登录页面为login.html 后面配置的.anyRequest().authenticated()是所有请求都登录认证,陷入了死循环. 所以需要将 login.html放行不需要登录认证

这边修改一下代码

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /** http.httpBasic() //开启httpBasic认证
         .and().authorizeRequests().anyRequest().authenticated(); //所有请求都需要认证之后访问
         */
        http.formLogin().loginPage("/login.html")//开启表单认证
              //  .and().authorizeRequests() //放行登录页面
            //    .anyRequest().authenticated();
                .and().authorizeRequests().antMatchers("/login.html").permitAll() //放行登录页面
                .anyRequest().authenticated();
    }

提示404了。这是怎么回事?

该工程页面已经整合了 thymeleaf ,那我们直接访问login.html就不行了,他需要请求之后然后跳转到该页面,那我们就写个方法让他跳转到该页面呗;

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

然后我们再修改一下SecurityConfig

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /** http.httpBasic() //开启httpBasic认证
         .and().authorizeRequests().anyRequest().authenticated(); //所有请求都需要认证之后访问
         */
        http.formLogin().loginPage("/login.html")//开启表单认证
              //  .and().authorizeRequests() //放行登录页面
            //    .anyRequest().authenticated();
             //   .and().authorizeRequests().antMatchers("/login.html").permitAll() //放行登录页面
                .and().authorizeRequests().antMatchers("/toLoginPage").permitAll() //放行登录页面
                .anyRequest().authenticated();
    }

重新启动运行,结果如下

登录是正常了,只不过样式没有了,估计是被security拦截掉了,打开控制台显示css,images,js都302了;

SecurityConfig 继承 WebSecurityConfigurerAdapter后,有三个 configure 方法,其中有一个是 configure(WebSecurity web),目测是web相关的东西,如下

    @Override
    public void configure(WebSecurity web) throws Exception {
        //解决静态资源被拦截的问题
        web.ignoring().antMatchers("/css/**","/images/**","/js/**");
    }

忽略掉和静态资源相关的东西,继续访问如下:

 霍,没问题了!

Spring Security 中,安全构建器 HttpSecurity 和 WebSecurity 的区别是 :

WebSecurity 不仅通过 HttpSecurity 定义某些请求的安全控制,也通过其他方式定义其他某些 请求可以忽略安全控制;

HttpSecurity 仅用于定义需要安全控制的请求(当然 HttpSecurity 也可以指定某些请求不需要 安全控制);

可以认为 HttpSecurity 是 WebSecurity 的一部分, WebSecurity 是包含 HttpSecurity 的更大 的一个概念;

构建目标不同

WebSecurity 构建目标是整个 Spring Security 安全过滤器 FilterChainProxy

HttpSecurity 的构建目标仅仅是 FilterChainProxy 中的一个 SecurityFilterChain

表单登录

页面问题解决了,下面我们来解决一下表单登陆的问题,上面15个过滤器链有个UsernamePasswordAuthenticationFilter是处理表单登录的;打开源码看一下都有些啥子。

 在源码中可以观察到, 表单中的input的name值是 username 和 password, 并且表单提交的路径 为 /login , 表单提交方式method为 post ,

这些可以修改为自定义的值.

修改一下config配置类以及login页面

    @Override
    protected void configure(HttpSecurity http) throws Exception {
​
/*        http.httpBasic() //开启httpBasic认证
                .and().authorizeRequests().anyRequest().authenticated(); //所有请求都需要认证之后访问*/
​
        http.formLogin() //开启表单认证
                .loginPage("/toLoginPage") // 自定义登陆页面
                .loginProcessingUrl("/login") //表单提交路径
                .usernameParameter("username").passwordParameter("password") //自定义input额name值和password
                .successForwardUrl("/") //登录成功之后跳转的路径
                .and().authorizeRequests().antMatchers("/toLoginPage").permitAll() //放行登录页面
                .anyRequest().authenticated()
                .and().csrf().disable();//关闭csrf防护
    }

login.html

 代码修改后重启完成登录

这时候又出现了新的坑,

index.html

发现行内框架 iframe 这里出现问题了. Spring Security下,X-Frame-Options默认为DENY,非Spring Security环境下,X-Frame-Options的默认大多也是DENY,这种情况下,浏览器拒绝当前页面加载任何 Frame页面,设置含义如下:

DENY:浏览器拒绝当前页面加载任何Frame页面 此选择是默认的.

SAMEORIGIN:frame页面的地址只能为同源域名下的页面

允许iframe加载

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /** http.httpBasic() //开启httpBasic认证
         .and().authorizeRequests().anyRequest().authenticated(); //所有请求都需要认证之后访问
         */
/*        http.formLogin().loginPage("/login.html")//开启表单认证
              //  .and().authorizeRequests() //放行登录页面
            //    .anyRequest().authenticated();
             //   .and().authorizeRequests().antMatchers("/login.html").permitAll() //放行登录页面
                .and().authorizeRequests().antMatchers("/toLoginPage").permitAll() //放行登录页面
                .anyRequest().authenticated();*/
                 http.formLogin() //开启表单认证
                .loginPage("/toLoginPage") // 自定义登陆页面
                .loginProcessingUrl("/login") //表单提交路径
                .usernameParameter("username").passwordParameter("password") //自定义input额name值和password
                .successForwardUrl("/") //登录成功之后跳转的路径
                .and().authorizeRequests().antMatchers("/toLoginPage").permitAll() //放行登录页面
                .anyRequest().authenticated()
                 .and().headers().frameOptions().sameOrigin() //加载同源域名下iframe页面
                .and().csrf().disable();//关闭csrf防护
    }

 可以了

 

posted @ 2023-03-15 15:11  __破  阅读(160)  评论(0)    收藏  举报