目录

现象描述

问题排查

怀疑点

验证

改进


现象描述

微信预约小程序的后端服务使用了shiro,来对用户的请求进行鉴权。但是经常有用户反馈微信小程序经常抛出“请求错误,请重试”,导致客户预订失败,客户问题反馈了很就,一直没有查出来。

问题排查

1 错误代码定位,由于使用shiro开源框架作为用户鉴权。onAccessDenied方法在什么情况下会触发呢?Shiro先会根据cookie的sessionId去获取用户会话的session,当用户的权限不满足时,会被拒绝并进行onAccessDenied方法。

2 日志定位。在后端服务代码中加了大量埋点日志,可以发现当用户请求被拒绝的,总有一段日志报错。

2020-06-28 11:32:14.892[http-nio-8080-exec-2][WARN ] o.a.s.m.AbstractRememberMeManager.onRememberedPrincipalFailure:449  There was a failure while trying to retrieve remembered principals.  This could be due to a configuration problem or corrupted principals.  This could also be due to a recently changed encryption key, if you are using a shiro.ini file, this property would be 'securityManager.rememberMeManager.cipherKey' see: http://shiro.apache.org/web.html#Web-RememberMeServices. The remembered identity will be forgotten and not used for this request.
2020-06-28 11:32:14.892[http-nio-8080-exec-2][WARN ] o.a.s.m.DefaultSecurityManager.getRememberedIdentity:617  Delegate RememberMeManager instance of type [org.apache.shiro.web.mgt.CookieRememberMeManager] threw an exception during getRememberedPrincipals().
org.apache.shiro.crypto.CryptoException: Unable to execute 'doFinal' with cipher instance [javax.crypto.Cipher@2379893e].at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:462)at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:445)at org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:390)at org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:382)at org.apache.shiro.mgt.AbstractRememberMeManager.decrypt(AbstractRememberMeManager.java:482)at org.apache.shiro.mgt.AbstractRememberMeManager.convertBytesToPrincipals(AbstractRememberMeManager.java:419)at org.apache.shiro.mgt.AbstractRememberMeManager.getRememberedPrincipals(AbstractRememberMeManager.java:386)at org.apache.shiro.mgt.DefaultSecurityManager.getRememberedIdentity(DefaultSecurityManager.java:612)at org.apache.shiro.mgt.DefaultSecurityManager.resolvePrincipals(DefaultSecurityManager.java:500)at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:346)
--at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:688)at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1639)at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)at java.lang.Thread.run(Thread.java:748)
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.at com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:975)at com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1056)at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)at javax.crypto.Cipher.doFinal(Cipher.java:2164)at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:459)

这段日志的大概意思,由于Shiro组件的Cihper由于密钥不正确,导致解码错误而抛出异常。这段日志大概是发生,在shiro获取用户session,并且在解码时抛出的错误。

o.a.s.m.AbstractRememberMeManager.onRememberedPrincipalFailure:449  There was a failure while trying to retrieve remembered principals.  This could be due to a configuration problem or corrupted principals

3 源码排查。根据错误的日志堆栈,shiro的AbstractRememberMeManager在decrypt(),会使用密钥去解码。

进一步扒源码,默认的CipherKey是随机生成的,cipherService.generateNewKey()。

有shiroConfig的CookieRememberMeManager没有设置cipherKey,则会shiro随机生成cipherKey。

怀疑点

1 由于后端采用分布式部署,不同机器随机生成的cipherKey不相同,假设用户A先通过服务B进行鉴权,使用服务B的cipherKey进行解密,用户A在预订时,请求直接打到服务器C,那么Shiro会使用服务器C的cipherKey进行解密服务B加密的session,那就会抛出以上的错误。

验证

线上部署的两台机器,用户的登陆请求打到了服务器B,当用户的请求打到服务器A时,就会出现cipher异常,这样就验证了怀疑点是正确的。

改进

分布式服务,如果采用shiro组件去做鉴权,在CookieRememberMeManager一定要设置统一的cipherKey。

Shiro框架Given final block not properly padded问题解决相关推荐

  1. javax.crypto.BadPaddingException: Given final block not properly padded解决方案

    javax.crypto.BadPaddingException: Given final block not properly padded解决方案 参考文章: (1)javax.crypto.Ba ...

  2. exception javax.crypto.BadPaddingException: Given final block not properly padded

    exception javax.crypto.BadPaddingException: Given final block not properly padded CreationTime--2018 ...

  3. DESUtils 加解密时 Given final block not properly padded bug小记

    事情的经过是这个样子的...... 先说说问题是怎么出现的.根据客户需求,需要完成一个一键登录的功能,于是我的项目中就诞生了DesUtil,但是经过上百次用户测试,发现有一个用户登录就一直报错!难道又 ...

  4. javax.crypto.BadPaddingException: Given final block not properly padded 解决方法

    javax.crypto.BadPaddingException: Given final block not properly padded 解决方法 参考文章: (1)javax.crypto.B ...

  5. AES解密报错:Given final block not properly padded. Such issues can arise if a bad key is used during dec

    问题:系统登录账号密码密文传输,用AES加密之后:登录的时候抛出: javax.crypto.BadPaddingException: Given final block not properly p ...

  6. AES 解密报错:Given final block not properly padded. Such issues can arise if a bad key is used dur

    问题:系统登录账号密码密文传输,用AES加密之后:登录的时候抛出:Given final block not properly padded. Such issues can arise if a b ...

  7. “Given final block not properly padded. Such issues can arise if a bad key is used during“错误解决

    在做AES解密的时候,碰到了"Given final block not properly padded. Such issues can arise if a bad key is use ...

  8. Linux下运行java DES解密失败,报javax.crypto.BadPaddingException:Given final block not properly padded

    参考:http://blog.csdn.net/rj042/article/details/8196125 单点登录:https://github.com/ebnew/ki4so redis客户端操作 ...

  9. DES加解密时 Given final block not properly padded 的解决方案

    事情的经过是这个样子的...... 先说说问题是怎么出现的.根据客户需求,需要完成一个一键登录的功能,于是我的项目中就诞生了DesUtil,但是经过几百次测试,发现有一个登录直接报错!难道又遇到神坑啦 ...

  10. Linux环境AES解密报错:Given final block not properly padded. Such issues can arise if a bad key is used dur

    将代码替换: String charset = "utf-8"; KeyGenerator kg = KeyGenerator.getInstance("AES" ...

最新文章

  1. 在Python上使用OpenCV检测和跟踪行人
  2. 如何让机器获得幽默感——Goolge图学习技术揭秘
  3. mysql 锁机制 mvcc_轻松理解MYSQL MVCC 实现机制
  4. Android Camera的进化史
  5. android clipChildren的使用
  6. CodeCraft-20 (Div. 2) C. Primitive Primes 思维 + 数论
  7. SpringBoot自定义Starter(自动配置类)
  8. 【Python】Python实战从入门到精通之一 -- 教你深入理解Python中的变量和数据类型
  9. 绝不因寂寞而爱上别人
  10. valgrind检测内存泄露
  11. 为什么 我的博客还没文章?
  12. 【VS环境配置】海康SDK二次开发【亲测有用】
  13. 游戏IP手册:游戏IP的内涵元素
  14. 增强型绿植植被指数_植被指数--数据产品-国家青藏高原科学数据中心
  15. wincc嵌入式excel报表 该报表系统能够读取WINCC中历史归档数据,产生出EXCEL报表文件,同时在画面中EXCEL控件实时显示
  16. Linux文件颜色含义
  17. 转:诺贝尔经济学奖得主与数学
  18. Python学习路线图
  19. B - Bitwise Exclusive-OR Sequence
  20. 【原创】关于Golang和Rust对比及语言的选择思考

热门文章

  1. 接了个私单,结果对方有部分尾款迟迟不付,还好有留了个后门
  2. 天猫万能红外遥控器拆解
  3. 【5号课堂】scratch制作电子生日贺卡
  4. 会话、Cookie、Session、url重写
  5. 哪个平台的身份证实名认证接口服务比较靠谱?
  6. 文明与征服北条时宗最强阵容搭配指南
  7. 频域滤波—方波变换中的沃尔什变换与哈达玛变换
  8. VOT竞赛paper阅读笔记
  9. 划片机操作安全注意事项
  10. matlab在solver,matlab的solver