一.导包后直接使用
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)) { //标识符{noop} null是权限信息暂时用不上 return new LoginAdmin(new Admin(null,"admin","admin","{noop}123456"),null); }else{ throw new RuntimeException("用户不存在"); } } }
第三步,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(){ //这样的话就可以正常设置密码不用加{noop} 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")); } }
这样就实现了自定义数据库校验账号和密码。