PHPER转JAVA记录篇-spring boot+shiro+jwt+redis

本文记录了一位PHP开发者转向Java,使用Spring Boot、Shiro、JWT和Redis实现权限管理的过程。文中讨论了如何关闭Shiro的session并利用JWT进行身份验证,解决了每次调用登录接口导致的性能问题,以及如何将session存储优化为Redis缓存。此外,还提到了在AOP中处理权限问题的挑战和解决方案。
摘要由CSDN通过智能技术生成

一、场景描述

1、前言

基于上一篇spring boot 整合shiro,当时想把shiro引入到我们的spring boot中,引入完了之后,我发现一个问题,那就是shiro是基于session的。那么我是不是可以引入到接口来做呢?比如我们的会员系统,会员分为好几个级别【白银、黄金、铂金、钻石、星耀、王者、荣耀王者】,目前只有王者和荣耀王者才可以打巅峰赛。

2、模拟逻辑(纯属杜撰)

我们先模拟一种场景
角色有:silver、gold、platinum、diamonds、starshine、king、glory
会员有:user1、user2、user3…userX
权限有:common_activity(普通活动)、star_activity(星耀活动)、king_activity(王者活动)、call_up_mode(征召模式)、common_mode(普通竞技模式)…

我们可以说,首先配置角色和权限关系
1、silver、gold、platinum、diamonds、starshine、king、glory 都有 common_activity、common_mode
2、diamonds、starshine、king、glory 都有call_up_mode
2、starshine、king、glory 都有 star_activity
3、king、glory 都有 king_activity

写到这里,大家觉得也没毛病啊,就用shiro做权限管理,没问题的,但是因为我们兼容安卓和IOS,所以是不是涉及到前后端分离呢?这样session无效了,怎么办。

3、JWT如何配合shiro来完成权限

这个相关的文章一大堆:
1、spring-boot-shiro-jwt-redis实现登陆授权功能
2、spring-boot-shiro-jwt-redis

这类文章太多了,我们就不在赘述了,不过这里有一个东西可以注意一下。

 /*
         * 关闭shiro自带的session,详情见文档
         * http://shiro.apache.org/session-management.html#SessionManagement-
         * StatelessApplications%28Sessionless%29
         */
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);

这玩意如果不知道在哪?可以看看上面2篇参考文章。这里是说要把session关闭的一个逻辑,同时备注上也说了,参考:关闭shiro自带的session,详情见文档

二、度娘告诉我们的做法

1、每次都需要登录

我们可以结合他的shiroConfig对于JwtFilter的注入知道,每个请求,都必须先登录,然后在做权限判断。

JwtFilter

/**
     * 执行登录认证
     *
     * @param request
     * @param response
     * @param mappedValue
     * @return
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
   
        try {
   
            executeLogin(request, response);
            return true;
        } catch (Exception e) {
   
            throw new AuthenticationException("Token失效请重新登录");
        }
    }

    /**
     *
     */
    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
   
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String token = httpServletRequest.getHeader(CommonConstant.ACCESS_TOKEN);

        JwtToken jwtToken = new JwtToken(token);
        // 提交给realm进行登入,如果错误他会抛出异常并被捕获
        getSubject(request, response).login(jwtToken);
        // 如果没有抛出异常则代表登入成功,返回true
        return true;
    }

shiroRealm类

/**
     * 功能: 用来进行身份认证,也就是说验证用户输入的账号和密码是否正确,获取身份验证信息,错误抛出异常
     *
     * @param auth 用户身份信息 token
     * @return 返回封装了用户信息的 AuthenticationInfo 实例
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
   
        String token = (String) auth.getCredentials();
        if (token == null) {
   
            log.info("————————身份认证失败——————————IP地址:  " + CommonUtils.getIpAddrByRequest(SpringContextUtils.getHttpServletRequest()));
            throw new AuthenticationException("token为空!");
        }
        // 校验token有效性
        SysUser loginUser = this.checkUserTokenIsEffect(token);
        return new <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值