springSecurity-1
1. 创建项目
1.1 选择基础的依赖
1.2 创建测试接口
1.3 配置springSecurity账号密码
1.4 账号密码的由来
idea中搜索SecurityProperties.class
2. SpringSecurity配置类
定义用户名和密码
基于内存的用户名和密码,角色的定义,后边切换为数据库,目的在于搞明白springSecurity认证流程
java
/**
* @author cute050
* @createTime 2024年11月05日 10:32
* @description
* 使用的是spring Security 6.X.X 版本
* 1. 不需要继承其他的Security类
* 2. 需要使用@Configuration 才会被spring容器加载
* 3. 废弃了很多方法 比如and()方法,建议使用lambda表达式实现
*/
@Configuration
@EnableWebSecurity // 启动spring Security自定义配置
public class SecurityConfig {
// 自定义用户名和密码
@Bean
public UserDetailsService userDetailsService() {
// 定义用户信息
UserDetails adminUser = User.withUsername("admin")
.password("{noop}123456")
.roles("admin", "user")
.build();
UserDetails vipUser = User.withUsername("user")
.password("{noop}123456")
.roles( "user")
.build();
// 将用户存储到spring Security中
InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
// 创建两个用户
userDetailsManager.createUser(adminUser);
userDetailsManager.createUser(vipUser);
return userDetailsManager;
}
}
密码加密
java
@Bean
public PasswordEncoder passwordEncoder(){
// 构建密码编辑器
return new BCryptPasswordEncoder();
}
测试类
java
/**
* @author cute050
* @createTime 2024年11月05日 12:30
* @description
*/
@SpringBootTest
public class myTest {
@Autowired
private PasswordEncoder passwordEncoder;
@Test
public void test(){
String pass = "123456";
String result = passwordEncoder.encode(pass);
System.out.println("result====> " + result);
// 匹配密码
boolean matches = passwordEncoder.matches(pass, result);
System.out.println("matches====> " + matches);
}
}
3. 自定义登录页面
使用thymeleaf模板引擎实现
3.1 创建登录页面
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
3.2 创建登录页面
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义的登录页面</title>
</head>
<body>
<form th:action="@{/doLogin}" method="post">
用户名: <input name="username" placeholder="请输入用户名"> <br/>
密码: <input name="password" placeholder="请输入密码" type="password"> <br/>
<input type="submit" value="登录">
</form>
</body>
</html>
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
恭喜你 登录成功!
</body>
</html>
java
@GetMapping("/toLogin")
public String toLogin(){
System.out.println("跳转到登录页面");
return "login";
}
@GetMapping("/index")
public String index(){
return "index";
}
java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// 配置关闭csrf
http.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth ->
auth.requestMatchers("/toLogin")
.permitAll()
.anyRequest()
.authenticated())
.formLogin(form -> form.loginPage("/toLogin") // 跳转到自定义的登录页面
.loginProcessingUrl("/doLogin") // 处理前端请求 与form表单的action一致
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/index") // 请求到index页面
);
return http.build();
}
yml
spring:
security:
user:
name: admin
password: 123456
4. 基于请求的授权
java
http.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth ->
auth
// .requestMatchers("/test1").hasRole("admin")
// .requestMatchers("/test1").hasAnyRole("admin", "user")
.requestMatchers("/test1").hasAuthority("test1:show")
.requestMatchers("/toLogin")
.permitAll()
.anyRequest()
.authenticated())
.formLogin(form -> form.loginPage("/toLogin") // 跳转到自定义的登录页面
.loginProcessingUrl("/doLogin") // 处理前端请求 与form表单的action一致
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/index") // 请求到index页面
);
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
// 定义用户信息
UserDetails adminUser = User.withUsername("admin")
.password("$2a$10$3oAw9LES8Kw2UAHR.59aEe0MELHzeyjBPZvzQoFbYvHJ.UvfbjnKi")
.roles("admin")
.build();
UserDetails vipUser = User.withUsername("user")
.password("$2a$10$3oAw9LES8Kw2UAHR.59aEe0MELHzeyjBPZvzQoFbYvHJ.UvfbjnKi")
.roles("user")
.build();
// 将用户存储到spring Security中
InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
// 创建两个用户
userDetailsManager.createUser(adminUser);
userDetailsManager.createUser(vipUser);
return userDetailsManager;
}
@Bean
public PasswordEncoder passwordEncoder() {
// 构建密码编辑器
return new BCryptPasswordEncoder();
}
5. 基于方法鉴权
在SpringSecurity6版本中@EnableGlobalMethodSecurity被弃用,取而代之的是@EnableMethodSecurity。默认情况下,会激活pre-post注解,并在内部使用AuthorizationManager。
新老API区别
此@EnableMethodSecurity替代了@EnableGlobalMethodSecurity。提供了以下改进:
使用简化的AuthorizationManager。 支持直接基于bean的配置,而不需要扩展GlobalMethodSecurityConfiguration 使用Spring AOP构建,删除抽象并允许您使用Spring AOP构建块进行自定义 检查是否存在冲突的注释,以确保明确的安全配置 符合JSR-250 默认情况下启用@PreAuthorize、@PostAuthorize、@PreFilter和@PostFilter