Spring Security是一个高度自定义的安全框架,它和Shiro很像。利用Spring IOC/DI和AOP功能,为系统提供了声明式安全访问控制功能,减少了为系统安全而编写大量重复代码的工作。
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.0.RELEASEversion>
<relativePath/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<version>2.3.0.RELEASEversion>
dependency>
dependencies>
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class,args);
}
}
账号一般默认是user,密码的话呢,打开IDEA,下面控制台就会显示。每次显示的密码都不一样。
spring.security.user.name=smallming
spring.security.user.password=smallming
在我们什么都没有配置的时候,账号和密码是由Spring Security定义生成的。而在实际项目中,账号和密码其实都是从数据库里面查询出来的。 所以我们要通过自定义逻辑控制认证逻辑。
那么现在我需要自定义逻辑,那么我就只需要实现UserDetailsService接口就可以了。
我们从这个接口可以看到,返回值是一个UserDetails的接口,我们点进源码看一看
其中构造方法有两个,调用其中任何一个都可以实例化UserDetails实现类User类的实例。而三个参数的构造方法实际上也是调用7个参数的构造方法。有时间的话可以根据package org.springframework.security.core.userdetails路径点进源码看一看
此处的用户名应该是客户端传递过来的用户名。而密码应该是从数据库中查询出来的密码。Spring Security会根据User中的password和客户端传递过来的password进行比较。如果相同则表示认证通过,如果不相同表示认证失败。
authorities里面的权限对于后面的授权操作是很有必要的,包含的所有内容为此用户具有的权限,如有里面没有包含某个权限,而在做某个事情时必须包含某个权限则会出现403。通常都是通过AuthorityUtils.commaSeparatedStringToAuthorityList(“”)来创建authorities集合对象的。参数是一个字符串,多个权限使用逗号分隔。
Spring Security要求容器中必须有PasswordEncoder实例(客户端密码和数据库密码是否匹配是由Spring Security 去完成的,Security中还没有默认密码解析器)。所以当自定义登录逻辑时要求必须给容器注入PaswordEncoder的bean对象
BCryptPasswordEncoder是Spring Security官方推荐的密码解析器,平时多使用这个解析器。
BCryptPasswordEncoder是对bcrypt强散列方法的具体实现。是基于Hash算法实现的单向加密。可以通过strength控制加密强度,默认10.
@SpringBootTest
@RunWith(SpringRunner.class)
public class Test {
@Test
public void test(){
//创建解析器
PasswordEncoder passwordencoder = new BCryptPasswordEncoder();
//对密码进行加密
String password = passwordencoder.encode("369613719");
System.out.println("password : "+password);
//判断原字符加密后和内容是否匹配
boolean result = passwordencoder.matches("369613719",password);
System.out.println("result : "+result);
}
}