【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)

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

相关推荐
zhangx1234_19 分钟前
javaEE 多线程1
java·linux·服务器
鬼手点金24 分钟前
opencode-crawl4ai使用建议
java·开发语言·人工智能·python·机器学习
专业程序开发源38 分钟前
springboot校园志愿者管理系统28562-计算机课程设计、毕业设计
java·spring boot·后端·python·django·php·课程设计
thefool11226642 分钟前
多线程 2
java
daidaidaiyu10 小时前
ThingsBoard 集群的核心逻辑源码分析
java
我可能是个假开发11 小时前
FTP Unicode 文件名导致 `550` 的问题分析与解决方案
java·开发语言·spring
caoerzhong11 小时前
中小企业上 WMS 该先上哪几块:JeeWMS 开源 Java 仓库管理系统的分批上线清单
java·python·开源
【JAVA】玩家12 小时前
Spring核心原理全解析:从零到生产实战
java·后端·spring
Wang's Blog13 小时前
Java框架 SpringCloud 快速入门: 实现 Feign 最佳实践(抽取方式)
java·spring cloud
MandalaO_O14 小时前
IDEA 开发(快捷键 + 调试 + 序列化)
java·ide·intellij-idea