3.spring-security自定义表单登录页面
spring-security自定义表单登录页面
在config包下编写SecurityConfiguration配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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放行不需要登录认证
这边修改一下代码
1 2 3 4 5 6 7 8 9 10 11 | @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就不行了,他需要请求之后然后跳转到该页面,那我们就写个方法让他跳转到该页面呗;
1 2 3 4 | @RequestMapping( "/toLoginPage" ) public String toLoginPage() { return "login" ; } |
然后我们再修改一下SecurityConfig
1 2 3 4 5 6 7 8 9 10 11 12 | @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相关的东西,如下
1 2 3 4 5 | @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页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @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加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @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防护 } |
可以了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY