一.导包后直接使用
1.在pom文件中直接导入spring-boot-starter-security包,重启项目。
2.在浏览器中输入网址,就会让你输入账号和密码,如下图所示。
3.账号默认为user,密码在控制台会有显示如下图所示。
二.自定义账号密码校验,数据库校验
下图所展示的是SpringSecurity的默认的认证流程。
Authentication接口: 它的实现类,表示当前访问系统的用户,封装了用户相关信息。 AuthenticationManager接口:定义了认证Authentication的方法
UserDetailsService接口:加载用户特定数据的核心接口。里面定义了一个根据用户名查询用户信息的 方法。
UserDetails接口:提供核心用户信息。通过UserDetailsService根据用户名获取处理的用户信息要封装 成UserDetails对象返回。然后将这些信息封装到Authentication对象中。
系统会依次执行以上流程。
1.实现自定义账号密码校验
从认证流程中可以看出,输入的账号和密码,被封装成Authentication对象,之后又逐级调用接口,最后调用UserDetailsService接口的loadUserByUsername方法,所以我们只需重写该方法便可。
首先,建立如图所示相关包。
第二步,在service中创建impl包,在impl创建一个UserDetailsServiceImpl实现类,来实现UserDetailsService接口,并重写里面的loadUserByUsername方法。(注意由于有默认的加密规则所以我们存储的密码暂时要加标识符{noop})否则会报错。
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//可以从数据库中根据用户名,来查询相关用户。
//在这里我用的是固定值,账号admin,密码123456
if ("admin".equals(username)) {
System.out.println(111);
//标识符{noop} null是权限信息暂时用不上
return new LoginAdmin(new Admin(null,"admin","admin","{noop}123456"),null);
}
return null;
}
}
第三步,UserDetailsService中的loadUserByUsername方法要返回一个UserDetails对象,所以要构造一个实体类来实现UserDetails接口,并重写所有方法。在domain中创建一个LoginAdmin类来封装用户的相关信息,并实现UserDetails接口。(注意要把所有的false改为true)
@Data
@AllArgsConstructor
public class LoginAdmin implements UserDetails {
//实体类
private Admin admin;
private List<String> permissions;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
//重写getPassword()和getUsername(),使其返回实体类账号和密码
@Override
public String getPassword() {
return admin.getAdminPwd();
}
@Override
public String getUsername() {
return admin.getAdminName();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
成功效果如下:
密码错误如下:
第四步,配置加密方式,在config中创建配置类SecurityConfig,并继承WebSecurityConfigurerAdapter,具体代码如下:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public BCryptPasswordEncoder getPasswordEncoder(){
return new BCryptPasswordEncoder();
}
}
第五步测试,把第二步的密码换成单元测试出来的加密后密文。
@SpringBootTest
class SecurityApplicationTests {
@Test
void contextLoads() {
BCryptPasswordEncoder bpe = new BCryptPasswordEncoder();
System.out.println(bpe.encode("123456"));
//原文123456,加密后为"$2a$10$i5GiJhejo5XzCts2xMikK.1eUEeV6YzwXEYk9Z.XW2IEFnzaEYhCy"
//每次加密的密文都不一样
System.out.println(bpe.matches("123456", "$2a$10$i5GiJhejo5XzCts2xMikK.1eUEeV6YzwXEYk9Z.XW2IEFnzaEYhCy"));
}
}
这样就实现了自定义数据库校验账号和密码。