本质:获取用户名密码验证登陆状态,密码匹配通过,查询该用户的权限角色数据,放到内存中,设置放行路径,Controller再拦截较验
基于数据库的用户角色配置
1,创建 UserService
定义的 UserService 实现 UserDetailsService 接口,并实现该接口中的 loadUserByUsername 方法,该方法将在用户登录时自动调用。
loadUserByUsername 方法的参数就是用户登录时输入的用户名,通过用户名去数据库中查找用户:
- 如果没有查找到用户,就抛出一个账户不存在的异常。
- 如果查找到了用户,就继续查找该用户所具有的角色信息,并将获取到的 user 对象返回,再由系统提供的 DaoAuthenticationProvider类去比对密码是否正确。
@Service public class UserService implements UserDetailsService { @Autowired private UserMapperDao userMapperDao; @Autowired private PasswordEncoder passwordEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userMapperDao.loadUserByUsername(username); //查询登陆用户的数据库信息 if (user == null) { throw new UsernameNotFoundException("账户不存在!"); } // 我的数据库用户密码没加密,这里手动设置 String encodePassword = passwordEncoder.encode(user.getPassword()); System.out.println("加密后的密码:" + encodePassword); user.setPassword(encodePassword); List<Role> userRoles = userMapperDao.getUserRolesByUid(user.getId()); user.setUserRoles(userRoles); return user; } }
2.配置 Spring Security
Spring Security 大部分配置与前文一样,只不过这次没有配置内存用户,而是将刚刚创建好的 UserService 配置到 AuthenticationManagerBuilder 中。
@Configuration public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; // 指定密码的加密方式 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } // 配置用户及其对应的角色 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService); } // 配置基于内存的 URL 访问权限 @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // 开启 HttpSecurity 配置 .antMatchers("/admin/**").hasRole("ADMIN") // admin/** 模式URL必须具备ADMIN角色 .antMatchers("/user/**").access("hasAnyRole('ADMIN','USER')") // 该模式需要ADMIN或USER角色 .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") // 需ADMIN和DBA角色 .anyRequest().authenticated() // 用户访问其它URL都必须认证后访问(登录后访问) .and().formLogin().loginProcessingUrl("/login").permitAll() // 开启表单登录并配置登录接口 .and().csrf().disable(); // 关闭csrf }
3.运行测试
@RestController public class HelloController { @GetMapping("/admin/hello") public String admin() { return "hello admin"; } @GetMapping("/user/hello") public String user() { return "hello user"; } @GetMapping("/db/hello") public String db() { return "hello db"; } @GetMapping("/hello") public String hello() { return "hello"; } }
参考https://www.cnblogs.com/dw3306/p/12751373.html
https://www.cnblogs.com/youngdeng/p/12869018.html