【SpringSecurity】SpringSecurity安全框架授权

授权

权限系统要实现的效果:不同的用户可以使用不同的功能

在后台进行用户权限的判断,判断当前用户是否有相应的权限,必须具有所需权限才能进行相应的操作。

在 SpringSecurity 中,默认使用 FilterSecurityInterceptor 进行权限校验。在 FilterSecurityInterceptor 中会从SecurityContextHolder 获取其中的 Authentication,然后获取其中的权限信息。当前用户是否拥有访问当前资源所需的权限。所以我们在项目中只需要把当前登录用户的权限信息也存入 Authentication,然后设置我们的资源所需要的权限即可。

首先开启相关配置。

java 复制代码
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // ......
}

使用对应的注解。@PreAuthorize

java 复制代码
@RestController
@RequestMapping("/user")
public class SysUserController {
    @Resource
    private SysUserService sysUserService;
    // 登录方法......
    // 退出登录......
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('USER1')")
    public ResultJSON list() {
        return ResultJSON.success();
    }
}

封装权限信息

写 UserDetailsServiceImzho 中,在查询出用户后还要获取对应的权限信息,封装到 UserDetails 中返回。

把权限信息写死封装到 UserDetails 中进行测试。

修改 UserDetails 的实现类 LoginUser,让其能封装权限信息。

java 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginUser implements UserDetails {
    private SysUser sysUser;
    private List<String> permissions;

    public LoginUser(SysUser sysUser, List<String> permissions) {
        this.sysUser = sysUser;
        this.permissions = permissions;
    }
    //存储SpringSecurity所需要的权限信息的集合
    @JSONField(serialize = false)
    private List<GrantedAuthority> authorities;
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        if (authorities != null) {
            return authorities;
        }
        authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(String.join(",",permissions));
        return authorities;
    }
    // 其他方法......
}
java 复制代码
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Resource
    private SysUserDao sysUserDao;
    @Override
    public UserDetails loadUserByUsername(String username)
            throws UsernameNotFoundException {
        // 根据用户名查询用户信息
        SysUser sysUser = sysUserDao.selectOne(new QueryWrapper<SysUser>()
                .eq("user_name", username));
        if (Objects.isNull(sysUser)) {
            throw new RuntimeException("用户名或密码错误");
        }
        // 从数据库中获取权限列表
        List<String> list = new ArrayList<>;
        list.add("USER1");
        // list.add("USER2");
        // 返回用户信息 和 权限集合
        return new LoginUser(sysUser, list);
    }
}

在 JwtAuthenticationTokenFilter 中修改如下代码

UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser,null,loginUser.getAuthorities());

java 复制代码
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Resource
    private RedisCache redisCache;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //......
        //存入SecurityContextHolder
        //TODO 获取权限信息封装到Authentication中
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginUser,null,loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //放行
        filterChain.doFilter(request, response);
    }
}

分别调用接口运行测试

java 复制代码
@RestController
@RequestMapping("/user")
public class SysUserController {
    @Resource
    private SysUserService sysUserService;
    // 登录方法......
    // 退出登录......
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('USER1')")
    public ResultJSON list() {
        return ResultJSON.success();
    }
}
java 复制代码
@RestController
@RequestMapping("/order")
public class SysOrderController {
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('USER2')")
    public ResultJSON list() {
        return ResultJSON.success();
    }
}

从数据库查询权限信息

RBAC 权限模型(Role-Based Access Control)

基于角色的权限控制。这是目前最常被开发者使用也是相对易用、通用权限模型。

相关推荐
小白的代码日记4 分钟前
java-反射精讲
java·开发语言
MaCa .BaKa15 分钟前
37-智慧医疗服务平台(在线接诊/问诊)
java·vue.js·spring boot·tomcat·vue·maven
碎梦归途23 分钟前
23种设计模式-行为型模式之模板方法模式(Java版本)
java·开发语言·jvm·设计模式·软考·模板方法模式·软件设计师
八股文领域大手子29 分钟前
Spring Boot Controller 如何处理HTTP请求体
java·开发语言·sql·spring·spring cloud
tanxiaomi29 分钟前
Java中对象集合转换的优雅实现【实体属性范围缩小为vo】:ListUtil.convert方法详解
java·spring boot·mybatis
odng30 分钟前
请求从发送到页面渲染的全过程
java
某不知名網友35 分钟前
linux_进程地址空间(虚拟地址空间)
java·linux·算法
每次的天空1 小时前
移动应用开发:自定义 View 处理大量数据的性能与交互优化方案
android·java·学习·交互
纪元A梦1 小时前
贪心算法应用:最小反馈顶点集问题详解
java·算法·贪心算法
九转苍翎2 小时前
Java SE(10)——抽象类&接口
java