简介
- 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. 自定义权限注解,支持基于注解和配置表多种方式配置过滤规则
注解的使用方式
配置表方式
最后的结果
注意:这里的顺序是配置表的配置会覆盖注解的
####2. 封装校验核心逻辑,抽离业务接口
####3. InitBean 初始化对象
####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支持关掉
- SessionStorageEvaluator
/**
* JWT 下禁用session, 不保存用户登录状态。保证每次请求都重新认证。
* 需要注意的是,如果用户代码里调用Subject.getSession()还是可以用session,如果要完全禁用,要配合下面的noSessionCreation的Filter来实现
*/
protected SessionStorageEvaluator createSessionStorageEvaluator() {
DefaultWebSessionStorageEvaluator sessionStorageEvaluator = new DefaultWebSessionStorageEvaluator();
sessionStorageEvaluator.setSessionStorageEnabled(false);
return sessionStorageEvaluator;
}
- 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可以作为子项目直接集成在项目中
公众号
五分钟了解前沿技术,大数据,微服务,区域链,提供java前沿技术干货,独立游戏制作技术分享
如果这篇文章对你有帮助请给个star
来源:CSDN
作者:wqr503
链接:https://blog.csdn.net/wqr503/article/details/104049065