前言
在上一章中,我带你去了解Spring 第一种Security认证方法,但这种基本认证方法,UI效果不美观,安全性也很差,好像什么都没有,所以有更好的认证方法吗?是的!接下来,我将向您介绍一种新的认证方法,即Form表格认证。
一. Form表单认证1. 认证方式我们从前面的文章中了解到,Spring Security中的认证方法可分为HTTP水平和表单水平,常见的认证方法如下:
2. 表格认证简介
- ①. HTTP基础认证;
- ②. Form表格认证;
- ③. HTTP摘要认证;
事实上,在SpringBoot开发环境中,只要我们添加Spring Security的依赖包将自动实现表单认证。是这样吗? 让我们来看看websecurityconfiguradapter类configgg(HttpSecurity http)在该方法中,可以看到以下默认实现。
因此,在SpringBoot环境中,表单认证是默认支持的。
3. 表格认证效果回想一下,我们在前一章中创建的第一个Spring Security项目的效果实际上是表格认证。每次我们访问Web接口,我们都会重新定位Security自己的标志登录页面,这是表格认证的效果。
4. 表单认证中的预置url和页面在这个时候,一些朋友可能会想,为什么表格认证会有上述效果?这是因为一些URL和页面自动配置在默认的formlogin配置中:
- /login(get) : 只要我们访问任何需要认证的请求,我们就会跳转到这个登录界面。
- /login(post) : post请求会触发此接口。点击登录页面时,默认登录页面表中的action与login接口相关。
- /login?error: 当用户名或密码错误时,它会跳转到页面。
- /: 登录成功后,如果配置index,默认跳转到页面。.html页面,然后 ”/“ 会重定向到index.html页面,当然,这个页面应该自己实现。
- /logout: 注销页面。
- /login?logout: 注销成功后跳转到的页面。
由此可见,SpringSecurity默认有两个login,即登录页面和登录接口的地址 /login:
- GET http://localhost:8080/login
- POST http://localhost:8080/login
如果是 GET 请求意味着您想访问登录页面;如果是, POST 请求意味着您想提交登录数据。
我们可以简单地了解这些URL接口。
二. 自定义表格认证配置在第一节,我们只了解了Spring Security内部是如何实现默认表单认证的,那么我们如何定制表单认证配置呢?
接下来,我将带您创建一个新的model,解释如何实现自定义表格认证,以及项目的具体创建过程。请参考《Spring Security系列教程03-创建SpringSecurity项目。
1. 创建Securityconfig配置类别我们先写一个类,继承自Websecurityconfigureradapter父类,其作用如下:
- 验证所有请求;
- 允许用户使用表达登录进行身份验证;
- HTTP基本认证允许用户使用。
代码如下:
package com.yyg.security.config;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;/** * @Author: 一一哥 * @Blame: yyg * @Since: Created in 2021/4/14 */@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //super.configure(http); ////配置表的认证方法 http.authorizeRequests() .anyRequest() .authenticated() .and() //打开表格认证 .formLogin(); }}
在Spring上添加@enablewebsecurity注释后,我们将自动被Spring发现和注册。在configure()方法中,我实施了formlogin()方法,其功能是打开表格认证。
2. 代码结构我们来看看现在的代码结构,其实和上一篇文章的代码结构是一样的。朋友可以直接在你上一个案例的基础上修改。为了方便大家查看,我在这里建立了一个新的model。
3. 启动项目然后启动项目,访问我们定义的/hello接口时,将首先重定向/login页面。
302重定向在认证成功后再次发生在内部:
可以看出,从/login接口重定向到/hello接口。这样,我们就可以通过几行代码实现自定义的表格认证。这也很简单吗?这很简单。事实上,我们在开发过程中使用的各种框架并不难使用,主要是掌握其用法和内部原理。
三. 自定义表格认证的登录界面然而,一些合作伙伴可能会说,默认提供的表单登录页面看起来有点丑,或者与我们项目中其他页面的UI风格不一致。您能定制此登录页面吗?
第一章介绍Spring 正如Security所说,它的一个特点是它可以高度自定义,配置灵活,所以我们当然可以自定义登录页面。
1. 定义服务端代码如果要实现自定义登录页面,我们可以在上面定义SecurityConfig configure在类中重写(WebSecurity web) 和 configure(HttpSecurity http) 自定义登录页面采用loginPage()法配置,代码如下:
package com.yyg.security.config;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.builders.WebSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;/** * @Author: 一一哥 * @Blame: yyg * @Since: Created in 2021/4/14 */@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter { /** * 用来定义哪些要求需要忽略安全控制,必须接受安全控制的要求是什么?SecurityContext也可以在适当的时候清除,以避免内存泄漏, * 也可用于定义要求防火墙和要求拒绝处理器,此外,我们还打开Springg Security 这里还配置了Debug模式 */ @Override public void configure(WebSecurity web) throws Exception { //super.configure(web); web.ignoring() .antMatchers("/js/**", "/css/**", "/images/**"); } @Override protected void configure(HttpSecurity http) throws Exception { //super.configure(http); //2.配置自定义登录页面 http.authorizeRequests() .anyRequest() .authenticated() .and() .formLogin() ///加载自定义登录页面地址 .loginPage("/myLogin.html") .permitAll() .and() //注:crsf防护功能需要禁用,否则登录不成功 .csrf() .disable(); }}
以上代码是实现自定义登录页面的核心代码。
你会发现实现自定义表单认证的代码很简单,但是Spring 我们自定义的登录页面是如何在Security内部加载的?负责完成的类别或方法有哪些?要想了解这个原理,首先需要了解两个核心参数:Websecurity和HttpSecurity,接下来,我将带您分别了解这两个核心参数。
1.1 Websecurity执行流程让我们先看下图:
WebSecurity的执行流程图是我们要求的。
在configure中(WebSecurity web)方法中有一个核心参数:WebSecurity!在这一类中,定义了一个securityFilterchainbuilders集合,可以同时管理多个securityFilterchain过滤器链。当我们学习Web基础时,您可以回顾过滤器的知识点。这些过滤器的执行是否比servlet早?
当WebSecurity执行时,它将构建一个名称 ”springSecurityFilterChain“ 的 Spring BeanFilterChainProxy代理,它的作用是来 忽略安全控制可以定义哪些请求?必须接受安全控制的要求是什么?以及在适当的时候 清除Securitycontetextet 同时也可以用来避免内存泄漏 也可以在这里定义要求防火墙和拒绝处理器的请求 打开Spring Security Debug模式。
由于上述一系列Filter过滤器,我们可以使用web.ignoring() 配置想要忽略的静态资源的方法 URL 地址,这样这些静态资源就可以被识别和访问而不被拦截。
1.2 Httpsecurity作用了解了Websecurity的作用后,再带大家学习Httpsecurity的作用。
Httpsecurity用于构建包含一系列过滤器链的SecurityFilterchain。通常,我们的配置是围绕SecurityFilterchain进行的。
2. 页面定义在了解了内部执行原理后,我们将实现代码。首先,我们定制一个登录页面,主要是编写html代码和css样式。您可以充分发挥您的前端能力,编写您满意的登录页面。其核心代码如下:
<body> <p class="login"> <h2>Access Form</h2> <p class="login-top"> <h1>登录验证</h1> <form action="/myLogin.html" method="post"> <input type="text" name="username" placeholder="username" /> <input type="password" name="password" placeholder="password" /> <p class="forgot"> <a href="#">忘记密码</a> <input type="submit" value="登录" > </p> </form> </p> <p class="login-bottom"> <h3>新用户 <a href="#">注 册</a></h3> </p> </p></body>
注意:
form表单中action的值,请暂时写成“/myLogin.html“。
3. 代码结构此时,我们项目的包结构如下图所示:
4. 启动项目启动项目后,当我们访问接口时,我们会自动跳转到我们定义的/myLogin.在html页面上,输入用户名和密码后,您可以成功访问您的接口。
这时,小伙伴们会发现,我们的登录页面比之前默认的登录页面漂亮多了,赞一个!
四. 详细说明表格认证配置在上述章节中,我们实现了自定义的表格认证登录页面,但一些合作伙伴可能认为上述案例不够灵活,特别是一些关于表格的参数,可以自定义吗?你可以负责任地告诉你,一点问题都没有!因此,我们进一步完善了表格认证的配置,以满足我们更多的需求。
例如,我们现在想修改表格认证页面中请求参数的名称,定义认证失败时的错误处理页面,以及退出登录时的操作。这些可以定制配置,实现代码如下。
1. Securityconfig类定义
package com.yyg.security.config;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.builders.WebSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;/** * @Author: 一一哥 * @Blame: yyg * @Since: Created in 2021/4/14 */@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter { /** * 用来定义哪些要求需要忽略安全控制,必须接受安全控制的要求是什么?SecurityContext也可以在适当的时候清除,以避免内存泄漏, * 也可用于定义要求防火墙和要求拒绝处理器,此外,我们还打开Springg Security 这里还配置了Debug模式 */ @Override public void configure(WebSecurity web) throws Exception { //super.configure(web); web.ignoring() .antMatchers("/js/**", "/css/**", "/images/**"); } @Override protected void configure(HttpSecurity http) throws Exception { //super.configure(http); //3.进一步配置自定义登录页面 //拦截请求,创建Filtersecurityinterceptortterttertetptertet http.authorizeRequests() .anyRequest() .authenticated() ///用and表示配置过滤器的结束,为了创建和配置下一个过滤器 .and() //设置表单登录,创建Usernamepaswordautinticationfilterterter创建 .formLogin() .loginPage("/myLogin.html") .permitAll() //指成功登录后,是否总是跳转到登录成功url?它默认为false .defaultSuccessUrl("/index.html",true) ///post登录接口,系统实现登录验证 .loginProcessingUrl("/login") ///用户密码错误跳转接口 .failureUrl("/error.html") ///要认证的用户参数名,默许username .usernameParameter("username") ///要认证的密码参数名,默许pasword .passwordParameter("password") .and() //配置注销 .logout() ///注销接口 .logoutUrl("/logout") ////注销成功后跳转到接口 .logoutSuccessUrl("/myLogin.html") .permitAll() ////删除自定义cookie .deleteCookies("myCookie") .and() //注:crsf防护功能需要禁用,否则登录不成功 .csrf() .disable(); }}
2. 定制登录页面
此时,我们还修改了登录页面,主要是修改form表单中action的值。
<body> <p class="login"> <h2>Access Form</h2> <p class="login-top"> <h1>登录验证</h1> <form action="/login" method="post"> <input type="text" name="username" placeholder="username" /> <input type="password" name="password" placeholder="password" /> <p class="forgot"> <a href="#">忘记密码</a> <input type="submit" value="登录" > </p> </form> </p> <p class="login-bottom"> <h3>新用户 <a href="#">注 册</a></h3> </p> </p></body>
注意:
此时,form表单中action的值应写成“/login因为我们在配置类中通过了“loginProcessingUrl("/login在方法中做了明确的配置。
3. 定义错误处理页面小伙伴又问了一个问题。当我们输入错误的用户名和密码时,我们该怎么办?事实上,我们可以在认证失败后提供一个错误处理页面并跳转到此页面。让我们在这里做一个简单的实现,除了index.类似于这个页面的html页面是简单的模拟。
4. 代码结构此时,项目的包装结构如下图所示,请参考:
5. 启动项目测试在这个时候,如果我们访问自己的接口,比如/hello,将首先重定向到/myLogin.html页面,输入自己配置的用户名和密码,验证后重定向/index.在html页面中,否则将重定向到我们配置的/error.在html页面中。
5.1 重定向到/myLogin.html访问资源时,将首先重定位到自定义登录页面。
5.2 重定向到/index.html认证成功后,将重新定向index.html页面。
5.3 重定向到/error.html认证失败后,将重新定位到自定义的错误处理页面。
通过这种情况,你会发现,Spring Security的配置非常灵活。当然,这只是我们学习的开始。还有更多的内容要学。继续往下看!如果您有任何问题,请在评论区留言...