设置权限所需资源、封装权限信息
设置权限所需资源
SpringSecurity为我们提供了基于注解的权限控制方案,这也是我们项目中主要采用的方式。我们可以使用注解去指定访问对应的资源所需的权限。
但是要使用它我们需要先开启相关配置。
@EnableGlobalMethodSecurity(prePostEnabled = true)
在SecurityConfig配置类上面添加此注解,开启配置。
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) // 开启相关配置 public class SecurityConfig extends WebSecurityConfigurerAdapter {
然后就可以使用对应的注解。@PreAuthorize
HelloController控制层
@RestController public class HelloController { @RequestMapping("/hello") @PreAuthorize("hasAuthority('test')") public String hello() { return "hello"; } }
封装权限信息
我们前面在写UserDetailsServiceImpl时候说过,在查询用户后还要获取对应的权限信息,封装到UserDetails中返回。
我们先直接把权限信息写死封装到UserDetails中进行测试。
我们之前定义了UserDetails的实现类LoginUser,想要让其能封装权限信息就要对其进行修改。
LoginUser实现类
@Data @NoArgsConstructor public class LoginUser implements UserDetails { private User user; //存储权限信息 private List<String> permissions; public LoginUser(User user,List<String> permissions) { this.user = user; this.permissions = permissions; } //存储SpringSecurity所需要的权限信息的集合 @JSONField(serialize = false) private List<GrantedAuthority> authorities; @Override public Collection<? extends GrantedAuthority> getAuthorities() { if(authorities!=null){ return authorities; } //把permissions中字符串类型的权限信息转换成GrantedAuthority对象存入authorities中 authorities = permissions.stream(). map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); return authorities; } @Override public String getPassword() { return user.getPassword(); } @Override public String getUsername() { return user.getUserName(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
LoginUser修改完后我们就可以在UserDetailsServiceImpl中去把权限信息封装到LoginUser中了。我们写死权限进行测试,后面我们再从数据库中查询权限信息。
UserDetailsServiceImpl实现类
@Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private UserMapper userMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(User::getUserName,username); User user = userMapper.selectOne(wrapper); if(Objects.isNull(user)){ throw new RuntimeException("用户名或密码错误"); } //TODO 根据用户查询权限信息 添加到LoginUser中 List<String> list = new ArrayList<>(Arrays.asList("test","admin")); return new LoginUser(user,list); } }
修改JwtAuthenticationTokenFilter类
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());