springboot shiro jwt demo实战项目

简介

  • shiro 是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。
  • jwt JSON Web Token 是目前最流行的跨域认证解决方案,无状态会话。

项目乔迁

shiro处理无状态校验上存在session保留问题,已改为用java脑洞 springboot 轻量级JWT安全框架

Git地址

https://gitee.com/wqrzsy/lp-demo/tree/master/lp-shiro-jwt

更多demo请关注

springboot demo实战项目
java 脑洞
java 面试宝典
开源工具

项目分析

1. 自定义权限注解,支持基于注解和配置表多种方式配置过滤规则

springboot shiro jwt demo实战项目_第1张图片
QQ截图20190428154402.png

注解的使用方式


springboot shiro jwt demo实战项目_第2张图片
QQ截图20190428154424.png

配置表方式


springboot shiro jwt demo实战项目_第3张图片
QQ截图20190428154442.png

最后的结果


springboot shiro jwt demo实战项目_第4张图片
QQ截图20190428154600.png

注意:这里的顺序是配置表的配置会覆盖注解的

2. 封装校验核心逻辑,抽离业务接口

springboot shiro jwt demo实战项目_第5张图片
image.png

3. InitBean 初始化对象

springboot shiro jwt demo实战项目_第6张图片
image.png

4. jwt刷新 使用过滤器TokenRefreshFilter

判断header是否有token,如果有则判断是否到了刷新时间,如果是则刷新token重新放入到header中

 @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletResponse.setCharacterEncoding("utf-8");
        Object token = servletRequest.getAttribute(AccountAide.JWT_TOKEN_NAME);
        if (token != null) {
            refreshJwtToken(WebUtils.toHttp(servletRequest), WebUtils.toHttp(servletResponse), token.toString());
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

    protected void refreshJwtToken(HttpServletRequest request, HttpServletResponse response, String jwtToken) {
        try {
            //ZoneId.systemDefault() 时区
            //签发时间
            LocalDateTime issueTime = LocalDateTime.ofInstant(JwtUtils.getIssuedAt(jwtToken).toInstant(), ZoneId.systemDefault());
            if (this.getRefreshTime(issueTime).isBefore(LocalDateTime.now())) {
                Long uid = JwtUtils.getUid(jwtToken);
                AccountInfo accountInfo = accountInfoService.getAccountInfo(uid);
                AccountAide.bindJwtToken(accountInfo, request, response, shiroConfig.getTokenExpireTime());
            }
        } catch (Exception e) {
            LOGGER.error("刷新JWT令牌异常: ", e);
        }
    }

5. 禁用session

因为jwt无需session支持,所以要把默认session支持关掉

  1. SessionStorageEvaluator
    /**
     * JWT 下禁用session, 不保存用户登录状态。保证每次请求都重新认证。
     * 需要注意的是,如果用户代码里调用Subject.getSession()还是可以用session,如果要完全禁用,要配合下面的noSessionCreation的Filter来实现
     */
    protected SessionStorageEvaluator createSessionStorageEvaluator() {
        DefaultWebSessionStorageEvaluator sessionStorageEvaluator = new DefaultWebSessionStorageEvaluator();
        sessionStorageEvaluator.setSessionStorageEnabled(false);
        return sessionStorageEvaluator;
    }
  1. NoSessionCreationFilter
    其实NoSessionCreationFilter中只有一行代码,就是在进入shiroFilter之前把SESSION_CREATION_ENABLED这个属性设为false
public class NoSessionCreationFilter extends PathMatchingFilter {

    @Override
    protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        request.setAttribute(DefaultSubjectContext.SESSION_CREATION_ENABLED, Boolean.FALSE);
        return true;
    }
}

所以我们结合一下,直接把NoSessionCreationFilter 和我们的JwtAuthFilter结合一起

public class JwtAuthFilter extends AuthenticatingFilter {

    private static Logger logger = LoggerFactory.getLogger(JwtAuthFilter.class);

    /**
     * 合并 noSessionCreation Filter
     *
     * @param request
     * @param response
     * @param mappedValue
     * @return
     * @throws Exception
     */
    @Override
    public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        request.setAttribute(DefaultSubjectContext.SESSION_CREATION_ENABLED, Boolean.FALSE);
        return isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response, mappedValue);
    }

}

6. 配置表

shiro:
  login:
    token:
      expireTime: 300000
    password:
      expireTime: 300000
  filterChains:
logging:
  config: classpath:logback-boot.xml

7. 测试

http://localhost:8080/swagger-ui.html

demo项目导入

参考: https://www.jianshu.com/p/cd0275a2f5fb
注意:该DEMO可以作为子项目直接集成在项目中

如果这篇文章对你有帮助请给个star


springboot shiro jwt demo实战项目_第7张图片
image.png

你可能感兴趣的:(springboot shiro jwt demo实战项目)