SpringSecurity创建一个简单的自定义表单的认证应用
1、SpringSecurity 自定义表单
在 Spring Security 中创建自定义表单认证应用是一个常见的需求,特别是在需要自定义登录页面、认证逻辑或添加额外的表单字段时。以下是一个详细的步骤指南,帮助你创建一个自定义表单认证应用。
2、基于 SpringSecurity 的简单的认证
【示例】SpringBoot 整合 SpringSecurity 创建一个简单的认证应用。
(1)创建 SpringBoot 项目,项目结构如下图:
(2)添加 Maven 依赖
在 pom.xml 配置文件中添加 Spring Security 依赖、Thymeleaf 模板引擎。
<!-- Spring Security 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.7.18</version>
</dependency>
<!-- Thymeleaf 模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
(3)创建配置类(核心代码)
创建 WebSecurityConfig 类(Spring Security 配置类),并添加 @EnableWebSecurity 注解和继承 WebSecurityConfigurerAdapter 类。
package com.pjb.securitydemo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
/**
* Spring Security 配置类
* @author pan_junbiao
**/
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests() //返回一个URL拦截注册器
.anyRequest() //匹配所有的请求
.authenticated() //所有匹配的URL都需要被认证才能访问
.and() //结束当前标签,让上下文回到 HttpSecurity
.formLogin() //启动表单认证
.loginPage("/myLogin.html") //自定义登录页面
.loginProcessingUrl("/auth/form") //指定处理登录请求路径
.permitAll() //使登录页面不设限访问
.and().csrf().disable(); //关闭CSRF的防御功能
}
/**
* 内存中添加登录账号(方式一)
*/
@Bean
public UserDetailsService userDetailsService()
{
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("admin").password("123456").roles("ADMIN").build());
manager.createUser(User.withUsername("user").password("123456").roles("USER").build());
manager.createUser(User.withUsername("panjunbiao").password("123456").roles("USER").build());
return manager;
}
/**
* 内存中添加登录账号(方式二)
* AuthenticationManagerBuilder 允许配置认证账号
*/
/*@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.inMemoryAuthentication()
.withUser("admin").password("123456").roles("ADMIN")
.and()
.withUser("user").password("123456").roles("USER")
.and()
.withUser("panjunbiao").password("123456").roles("USER");
}*/
/**
* 由于5.x版本之后默认启用了委派密码编译器,
* 因而按照以往的方式设置内存密码将会读取异常,
* 所以需要暂时将密码编码器设置为 NoOpPasswordEncoder
*/
@Bean
public PasswordEncoder passwordEncoder()
{
return NoOpPasswordEncoder.getInstance();
}
}
@EnableWebSecurity 是 Spring Security 提供的一个注解,用于启用 Spring Security 的 web 安全功能。当你在 Spring Boot 或 Spring MVC 应用程序中添加了@EnableWebSecurity 注解后,Spring Security 会自动配置一些默认的安全设置,比如基本的认证和授权机制。
WebSecurityConfigurerAdapter 是 Spring Security 框架中的一个关键组件,它作为一个适配器类,允许开发者通过继承它并重写相关方法来自定义 Web 应用的安全设置。WebSecurityConfigurerAdapter 实现了 WebSecurityConfigurer 接口,并提供了默认的 Web 安全配置。它允许开发者通过重写特定的方法来定制安全行为,如配置认证和授权规则、处理用户会话管理、跨站请求伪造(CSRF)防护等。
(4)编写控制器类
创建 IndexController 控制器类,实现跳转到首页,同时获取当前登录人的名称。
package com.pjb.securitydemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
/**
* 首页控制器
* @author pan_junbiao
**/
@Controller
public class IndexController
{
/**
* 首页
*/
@RequestMapping("/")
public String index(HttpServletRequest request)
{
//获取当前登录人
String userName = "未登录";
Principal principal = request.getUserPrincipal();
if(principal!=null)
{
userName = principal.getName();
}
//返回页面
request.setAttribute("userName",userName);
return "/index.html";
}
}
(5)编写登录页面
在 resources\static 资源目录下,创建 myLogin.html 页面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form name="myForm" action="/auth/form" method="post">
<table align="center">
<caption>用户登录</caption>
<tr>
<td>登录账户:</td>
<td>
<input type="text" name="username" placeholder="请输入登录账户" value="panjunbiao" />
</td>
</tr>
<tr>
<td>登录密码:</td>
<td>
<input type="password" name="password" placeholder="请输入登录密码" value="123456" />
</td>
</tr>
<!-- 以下是提交、取消按钮 -->
<tr>
<td colspan="2" style="text-align: center; padding: 5px;">
<input type="submit" value="提交" />
<input type="reset" value="重置" />
</td>
</tr>
</table>
</form>
</body>
</html>
(6)编写首页
在 resources\templates 资源目录下,创建 index.html 页面。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
<meta name="author" content="pan_junbiao的博客">
</head>
<body>
<h1 style="color: red">Hello,Spring Security</h1>
<p>博客信息:您好,欢迎访问 pan_junbiao的博客</p>
<p>博客地址:https://blog.csdn.net/pan_junbiao</p>
<p th:text="'当前登录人:' + ${userName}"></p>
<a href="/logout" onclick="return confirm('确认注销吗?');">登出</a>
</body>
</html>
(7)运行项目
(8)成功登录后,跳转至首页