SpringBoot整合SpringSecurity实现权限控制(一)

x33g5p2x  于2021-12-30 转载在 Spring  
字(2.0k)|赞(0)|评价(0)|浏览(466)

一、前言

  • 在《手把手教你通过SpringBoot实现邮箱注册码验证》文章中实现了基于邮箱的用户登录认证。
  • 在《Vue+SpringBoot 实现用户头像上传(附前后端源码)》文章中又添加了更新用户头像的方法与功能。
  • 为了安全起见,除了以上必备的用户认证(登录)识别用户是否合法外,还需要根据权限来控制用户是否能够执行某项操作。比如说我们希望给上传用户头像的方法加上权限控制,让有此权限的用户才能够进行更新头像。

二、实现原理

  • 1、给后台方法加上权限控制,根据用户角色的不同给用户分配不同的权限;
  • 2、后台服务在生成JWT令牌时写入用户所拥有的权限;
  • 3、用户登录后,在携带令牌访问后台某个方法时,后台服务需要判断令牌信息中是否有此方法对应的权限。

三、具体实现

  • 根据用户角色的不同给用户分配不同的权限的功能,我们将在后期来实现,本文先通过静态模拟的方法演示权限控制的原理。

3.1 给后台方法加上权限控制

  • 在Controller入口层的服务方法上添加注解@PreAuthorize,并指定此方法所需要的权限
// 给更新用户头像入口加上权限控制字符串(user:updateAvatar)
	@PreAuthorize("hasAuthority('user:updateAvatar')")
    @ApiOperation("修改用户头像")
    @PostMapping(value = "/updateAvatar")
    public ResponseEntity<Object> updateAvatar(@RequestParam MultipartFile avatar) {
        return  ResponseEntity.ok(sysUserService.updateAvatar(avatar));
    }
  • 加上此权限控制后,我们试着让前端来访问一下此控制层的更新头像方法,发现上传图片失败,并在控制台中提示403无权限的错误信息。

3.2 后台服务在生成JWT令牌时写入用户所拥有的权限

  • 接下来,我们要把给以上方法的权限赋给用户:修改认证服务的UserDetailServiceImpl类,将权限标识按照中间使用逗号分隔的语法组成一个字符串(静态模拟给用户加上权限控制字符 user:updateAvatar),最终提供给Spring security。
/** * 用户认证 * * @author zhuhuix * @date 2020-06-15 * @date 2021-08-23 静态模拟给用户加上权限控制字符 user:updateAvatar */
@RequiredArgsConstructor
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {

    private final SysUserService sysUserService;

    @Override
    public JwtUserDto loadUserByUsername(String username) {
        SysUser user;
        try {
            user = sysUserService.findByUserName(username);
        } catch (RuntimeException e) {
            // SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException
            throw new UsernameNotFoundException("无此用户", e);
        }
        if (user == null) {
            throw new UsernameNotFoundException("无此用户");
        } else {
            if (!user.getEnabled()) {
                throw new RuntimeException("账号未激活");
            }
            return new JwtUserDto(
                    user,
                    null,
                    AuthorityUtils.commaSeparatedStringToAuthorityList("user:updateAvatar")
            );
        }
    }
}
  • 试着重新让前端来访问一下此控制层的更新头像方法(一定要重新登录,即前台重新获取带有权限控制字符的Token),发现上传图片成功了。

四、跟踪jwt 令牌包含权限

  • 接下来我们在后台服务中设置断点,跟踪一下jwt令牌中是否包含有以上设置的权限控制字符串:以下图片中我们可以跟踪到用户上传的token中已经含有user:updateAvatar的权限控制字符串,即拥有了更新用户头像的权限。

相关文章