Springboot +spring security,认证方式---Form表单认证的实现(三)

news/2024/11/25 17:47:59/

一.简介

这篇文章来学习下security的认证方式其中的Form表单认证

二.Spring Security的认证方式

2.1什么是认证

认证:
就是用来判断系统中是否存在某用户,并判断该用户的身份是否合法的过程,解决的其实是用户登录的问题。认证的存在,是为了保护系统中的隐私数据与资源,只有合法的用户才可以访问系统中的资源。

2.2认证的方式

在Spring Security中,常见的认证方式可以分为HTTP层面和表单层面,常见的认证方式如下:

  1. HTTP基本认证;
  2. Form表单认证
  3. HTTP摘要认证;

这篇文章先讲HTTP基本认证

三. Form表单认证

3.1Form表单认证简介

对于表单认证,其实在SpringBoot开发环境中,只要添加了Spring Security的依赖包,就会自动实现表单认证。先看下源码,在WebSecurityConfigurerAdapter类的config(HttpSecurity http)方法中,可以看到如下实现,截图如下:
在这里插入图片描述
所以在SpringBoot环境中,默认支持的就是表单认证方式。

3.2表单认证效果

我们在访问某个Web接口之前,都会重定向到一个Security自带的login登录页面上,这个登录页面,就是表单认证的效果。截图如下:
在这里插入图片描述

3.3表单认证中的预置url和页面

为什么表单认证会有以上效果?这是因为在默认的formLogin配置中,自动配置了一些url和页面:

  1. /login(get): get请求时会跳转到这个页面,只要我们访问任意一个需要认证的请求时,都会跳转到这个登录界面。
  2. /login(post): post请求时会触发这个接口,在登录页面点击登录时,默认的登录页面表单中的action就是关联这个login接口。
  3. /login?error: 当用户名或密码错误时,会跳转到该页面。
  4. /: 登录成功后,默认跳转到该页面,如果配置了index.html页面,则 ”/“ 会重定向到index.html页面,当然这个页面要由我们自己实现。
  5. /logout: 注销页面。
  6. /login?logout: 注销成功后跳转到的页面。

由此可见,SpringSecurity默认有两个login,即登录页面和登录接口的地址都是 /login:

  1. GET http://localhost:8080/login
  2. POST http://localhost:8080/login

如果是 GET 请求,表示你想访问登录页面;如果是 POST 请求,表示你想提交登录数据。

四. 创建SpringSecurity项目

参考之前的文章,这边不做叙述。

五.代码实现

5.1创建SecurityConfig配置类

创建SecurityConfig类,继承自WebSecurityConfigurerAdapter父类,该类的作用如下:

  1. 验证所有请求;
  2. 允许用户使用表达登录进行身份验证;
  3. 允许用户使用Http基本认证。

代码如下:

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;@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//super.configure(http);//配置表单认证方式http.authorizeRequests().anyRequest().authenticated().and()//开启表单认证.formLogin();}
}

我们在SecurityConfig类上添加@EnableWebSecurity注解后,会自动被Spring发现并注册。在configure()方法中,我执行了formLogin()方法,该方法的功能就是开启表单认证。

5.2创建web接口

HelloController类的代码如下:


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController {@GetMapping("/hello")public String hello() {return "德玛西亚";}}

5.3yml配置文件

创建一个application.yml配置文件,配置如下:

spring:security:user:name: demaxiyapassword: 123

六.功能验证

6.1启动项目

接下来启动项目,访问我们定义的/hello接口时,首先会重定向到/login页面,截图如下:
在这里插入图片描述

我们只有输入自己配置的用户名和密码后,才可以正常访问/hello接口。

七.自定义表单认证的登录界面

7.1服务端代码定义

如果想实现自定义登录页面,可以在上面定义的SecurityConfig 类中,复写configure(WebSecurity web) 和 configure(HttpSecurity http) 方法,通过loginPage()方法来配置自定义登录页面,代码如下:

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;@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {/*** 用来定义哪些请求需要忽略安全控制,哪些请求必须接受安全控制;还可以在合适的时候清除SecurityContext以避免内存泄漏,* 同时也可以用来定义请求防火墙和请求拒绝处理器,另外我们开启Spring Security Debug模式也是这里配置的*/@Overridepublic void configure(WebSecurity web) throws Exception {//super.configure(web);web.ignoring().antMatchers("/js/**", "/css/**", "/images/**");}@Overrideprotected 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内部是如何加载我们自定义的登录页面的呢?有哪些类或方法来负责完成呢?如果想要弄明白这个原理,我们需要先了解2个核心参数:WebSecurity和HttpSecurity,接下来我带各位分别了解一下这2个核心参数。

7.1.1

WebSecurity执行流程,截图如下:
在这里插入图片描述
这是我们请求时,WebSecurity的执行流程图。

在configure(WebSecurity web)方法中,有个核心参数:WebSecurity类!在这个类里定义了一个securityFilterChainBuilders集合,可以同时管理多个SecurityFilterChain过滤器链,各位可以回顾我们学习Web基础时,关于过滤器的知识点,这些过滤器的执行是不是比Servlet更早?

当WebSecurity在执行时,会构建出一个名为 ”springSecurityFilterChain“ 的 Spring BeanFilterChainProxy代理类,它的作用是来 定义哪些请求可以忽略安全控制,哪些请求必须接受安全控制;以及在合适的时候 清除SecurityContext 以避免内存泄漏,同时也可以用来 定义请求防火墙和请求拒绝处理器,也可以在这里 开启Spring Security 的Debug模式。

因为有上面这一系列的Filter过滤器,我们就可以利用web.ignoring() 方法来配置想要忽略的静态资源 URL 地址,这样这些静态资源就可以不被拦截,从而可以被识别访问了。

7.1.2HttpSecurity作用

HttpSecurity的作用,截图如下:在这里插入图片描述
HttpSecurity用来构建包含一系列的过滤器链SecurityFilterChain,平常我们的配置就是围绕着这个SecurityFilterChain进行。

7.2页面定义

html核心代码如下:

<body><div class="login"><h2>Access Form</h2><div 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" /><div class="forgot"><a href="#">忘记密码</a><input type="submit" value="登录" ></div></form></div><div class="login-bottom"><h3>新用户&nbsp;<a href="#">注&nbsp;册</a></h3></div></div>
</body>

注意:

form表单中action的值,暂时先写成”/myLogin.html“。

7.3页面定义

启动项目后,我们访问接口时,就会自动跳转到自己定义的/myLogin.html页面上,输入用户名和密码后,就可以成功访问自己的接口。截图如下:
在这里插入图片描述

八.细化表单认证配置

修改表单认证页面中请求参数的名称,定义认证失败时的错误处理页面,处理退出登录时的操作等,这些都可以自定义配置,实现代码如下.

8.1定义SecurityConfig类

SecurityConfig类代码如下:

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;@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {/*** 用来定义哪些请求需要忽略安全控制,哪些请求必须接受安全控制;还可以在合适的时候清除SecurityContext以避免内存泄漏,* 同时也可以用来定义请求防火墙和请求拒绝处理器,另外我们开启Spring Security Debug模式也是这里配置的*/@Overridepublic void configure(WebSecurity web) throws Exception {//super.configure(web);web.ignoring().antMatchers("/js/**", "/css/**", "/images/**");}@Overrideprotected void configure(HttpSecurity http) throws Exception {//super.configure(http);//3.进一步配置自定义的登录页面   //拦截请求,创建FilterSecurityInterceptor http.authorizeRequests() .anyRequest().authenticated()//用and来表示配置过滤器结束,以便进行下一个过滤器的创建和配置.and() //设置表单登录,创建UsernamePasswordAuthenticationFilter.formLogin()                    .loginPage("/myLogin.html").permitAll()//指登录成功后,是否始终跳转到登录成功url。它默认为false.defaultSuccessUrl("/index.html",true)//post登录接口,登录验证由系统实现.loginProcessingUrl("/login")//用户密码错误跳转接口.failureUrl("/error.html")//要认证的用户参数名,默认username.usernameParameter("username")//要认证的密码参数名,默认password.passwordParameter("password").and()//配置注销.logout()//注销接口.logoutUrl("/logout")//注销成功后跳转到的接口.logoutSuccessUrl("/myLogin.html").permitAll()//删除自定义的cookie.deleteCookies("myCookie").and()//注意:需禁用crsf防护功能,否则登录不成功.csrf().disable();} 
}

8.2自定义登录页面

这时候把登录页面也跟着修改一下,主要是把form表单中action的值修改掉。前端代码如下:

<body><div class="login"><h2>Access Form</h2><div class="login-top"><h1>登录验证</h1><form action="/login" method="post"><input type="text" name="username" placeholder="username" /><input type="password" name="password" placeholder="password" /><div class="forgot"><a href="#">忘记密码</a><input type="submit" value="登录" ></div></form></div><div class="login-bottom"><h3>新用户&nbsp;<a href="#">注&nbsp;册</a></h3></div></div>
</body>

注意:
此时form表单中action的值,要写成”/login“,因为我们在配置类中通过“loginProcessingUrl(“/login”)”方法中做了明确的配置。

8.3定义错误处理页面

当输入了错误的用户名和密码后,这时候会怎么办呢?这里可以提供一个错误处理页面,当认证失败后跳转到这个页面即可。这里简单实现一下,另外index.html页面与该页面类似。
在这里插入图片描述

8.4启动项目

这时候如果访问自己的接口,比如/hello,会先重定向到/myLogin.html页面,输入自己配置的用户名和密码,经过验证后,才会重定向到/index.html页面中,否则会重定向到配置的/error.html页面中。

8.4.1重定向到/myLogin.html

访问资源时,会先重定向到自定义的登录页面。截图如下:
在这里插入图片描述

8.4.2重定向到/index.html

认证成功后,会重定向到index.html页面。
在这里插入图片描述

8.4.3重定向到/error.html

认证失败后,会重定向到自定义的错误处理页面。
在这里插入图片描述


http://www.ppmy.cn/news/108590.html

相关文章

JavaScript 进阶 (三)

目录 编程思想 面向过程编程 面向对象编程 构造函数 原型 原型 constructor 属性 对象原型 原型继承 原型链 编程思想 面向过程编程 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候再一个一个的依次 调用…

windows环境下,nginx部署vue工程

在 Windows 环境下部署 Vue 工程&#xff0c;可以使用 Nginx 作为 Web 服务器。下面是具体步骤&#xff1a; 1. 安装 Nginx 在 Windows 环境下安装 Nginx&#xff0c;可以从官网下载 Windows 版本的 Nginx&#xff0c;下载地址为&#xff1a;http://nginx.org/en/download.ht…

AndroidMVP架构与MVVM架构的对比(内附代码实例)

&#x1f604;&#x1f604;个人介绍 光子郎.进行开发工作七年以上&#xff0c;目前涉及全栈领域并进行开发。会经常跟小伙伴分享前沿技术知识&#xff0c;java后台、web前端、移动端&#xff08;Android&#xff0c;uniapp&#xff0c;小程序&#xff09;相关的知识以及经验体…

Linux command(inotify)

说明 fs.inotify.max_user_instances 变量是 Linux 系统中用于控制 inotify 实例数量的参数。inotify 是 Linux 内核提供的一种文件系统事件监控机制&#xff0c;它可以监控文件系统中的文件和目录&#xff0c;当文件或目录发生变化时&#xff0c;可以及时通知应用程序。 fs.…

全面理解:C++中list(双向链表)容器的基础概念与函数解析

list容器的基础概念 在 C 标准库中&#xff0c;list 是一种双向链表&#xff0c;允许在任何位置进行快速的插入和删除操作。 以下是一些关于 list 的基本信息。 存储&#xff1a;list 是一种双向链表结构&#xff0c;它不像 vector 或 array 那样提供连续的内存存储。 时间复杂…

IIC总线协议的死锁问题

目录 1. IIC的特性 2. IIC死锁问题分析 3. 常见的IIC死锁问题解决方法 1. IIC的特性 IIC协议是一个允许一主多从通信的协议&#xff0c;只能用于短距离通信&#xff0c;并且只需要两根信号线来交换信息。 IIC的两根信号是SCL和SDA&#xff0c;SCL是时钟信号线&#xff0c;S…

Java之路:构建坚实基础,系统学习Java技术的终极指南

无论是初学者还是有经验的专业人士&#xff0c;在学习一门新的IT技术时&#xff0c;都需要采取一种系统性的学习方法。作为一名Java技术er&#xff0c;下面我将介绍我是如何系统的学习Java技术的。 一、Java技术介绍 Java是一种广泛应用于软件开发的高级编程语言&#xff0c;…

docker的基本相关知识和操作

镜像相关操作命令&#xff1a; 访问DockerHub搜索镜像&#xff0c;https://hub.docker.com/ 查看本地镜像&#xff1a;docker images 搜索镜像 docker search redis &#xff08;搜索redis&#xff09; 拉取镜像&#xff1a;docker pull redis &#xff08;默认版本&#x…