十二、SpringBoot 优雅的集成Spring Security (4)

在service 层我们要注意一点,我们需要实现 UserDetailsService 接口。
我们先创建一个UserService 继承 UserDetailsService。然后创建一个UserServiceImpl 来时实现UserService 从而达到实现UserDetailsService的目的。这样做是为了保证项目结构的统一层次。

UserService public interface UserService extends UserDetailsService { } UserServiceImpl @Service @Slf4j @Transactional public class UserServiceImpl implements UserService { @Autowired UserMapper userMapper; @Autowired RolesMapper rolesMapper; @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { UserEntry user = userMapper.loadUserByUsername(s); if (user == null) { //避免返回null,这里返回一个不含有任何值的User对象,在后期的密码比对过程中一样会验证失败 return new UserEntry(); } //查询用户的角色信息,并返回存入user中 List<RoleEntry> roles = rolesMapper.getRolesByUid(user.getId()); user.setRoles(roles); return user; } }

可以看到,主要是为了实现 loadUserByUsername的方法。在这个方法中我们 loadUserByUsername和getRolesByUid 就是我们在mapper 定义的查询数据库数据的方法。

SecurityConfig

前面做了这么多,其实都是准备工作,主要的目的就是提供一个Bean 。做完上面这些,我们再回到 SecurityConfig 中,其实我们现在需要修改的很少了。
我们将用户写在内存的方法注释掉。通过数据库查询。

@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired UserService userService; @Bean public PasswordEncoder passwordEncoder() { // BCryptPasswordEncoder:Spring Security 提供的加密工具 return new BCryptPasswordEncoder(); } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService) .passwordEncoder(passwordEncoder());//passwoldEncoder是对密码的加密处理,如果user中密码没有加密,则可以不加此方法。注意加密请使用security自带的加密方式。 } }

可以和开始的 SecurityConfig 文件对比下,其实你就是多了一个userService,然后configure(AuthenticationManagerBuilder auth)中是通过userService 进行校验的。

测试

好了,其实到这里,我们就已经完成了,我们启动项目,就可以看到和之前写在内存中达到一样的效果。

在这里插入图片描述

过滤

以为到这就完了,其实还有一点哈哈。我们现在是所有的接口都需要先登录才能访问,没有登录的话就跳转到login界面。实际上我们肯定有些是不需要认证也可以访问的,比如以下静态文件或者注册的请求。
所以我们还是要配置一下过滤。

其实也很简单,一样的在 SecurityConfig 文件中 重写 configure(HttpSecurity http) 方法。
这里我直接参考官网上的。
https://spring.io/guides/gs/securing-web/

在这里插入图片描述

该configure(HttpSecurity)方法定义应保护哪些URL路径,不应该保护哪些URL路径。具体而言,“ /”和“ / home”路径配置为不需要任何身份验证。所有其他路径必须经过验证。
用户成功登录后,他们将被重定向到之前要求身份验证的页面。有一个由指定的自定义“ /登录”页面loginPage(),每个人都可以查看它。

我们代码中 把 loginPage("/login") 注释掉就好了,如果不注释的话,就需要我们自己写login 界面和请求。我们这里就用框架自带的。

@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("http://www.likecs.com/", "/hello").permitAll() .anyRequest().authenticated() .and() .formLogin() //.loginPage("/login") .permitAll() .and() .logout() .permitAll(); }

这样配置就说明 /hell 和 / 请求不会拦截,其他的请求,需要先登录才能访问。
为了更方便的看到效果,我们在HelloController 中再加两个方法

@RequestMapping("/hello2") public String hello2(){ return "hello adada"; } @RequestMapping("http://www.likecs.com/") public String hello3(){ return " qazqeee"; } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zydwzy.html