标签:builds sso issue shiro block defaults tin read identity
org.apache.shiro.crypto.CryptoException: Unable to execute ‘doFinal‘ with cipher instance [javax.crypto.Cipher@4e025e0a]. 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:604) at org.apache.shiro.mgt.DefaultSecurityManager.resolvePrincipals(DefaultSecurityManager.java:492) at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:342) at org.apache.shiro.subject.Subject$Builder.buildSubject(Subject.java:846) at org.apache.shiro.web.subject.WebSubject$Builder.buildWebSubject(WebSubject.java:148) at org.apache.shiro.web.servlet.AbstractShiroFilter.createSubject(AbstractShiroFilter.java:292) at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:359) at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) 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:200) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:836) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1747) 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) ... 35 more
每次登陆都会报这个错误,尝试了很多次都没解决,代码重编译后清除浏览器cookie登陆就会出现这个报错,虽然不影响登陆但是看着很不爽!!!!
问题产生的原因是rememberMe的cookie在第二次打开页面后shiro无法解密,经过查询资料以及代码跟踪发现了原因所在
先附上rememberMe管理器配置
@Bean public CookieRememberMeManager cookieRememberMeManager() { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); simpleCookie.setMaxAge(259200000); cookieRememberMeManager.setCookie(simpleCookie); return cookieRememberMeManager; }
然后跟踪管理器源码发现,rememberMeManager继承了AbstractRememberMeManager,然而AbstractRememberMeManager的构造方法中每次都会重新生成对称加密密钥!!!!意味着每次重启程序都会重新生成一对加解密密钥!!!
public AbstractRememberMeManager() { this.serializer = new DefaultSerializer<PrincipalCollection>(); AesCipherService cipherService = new AesCipherService(); this.cipherService = cipherService; setCipherKey(cipherService.generateNewKey().getEncoded()); } public void setCipherKey(byte[] cipherKey) { //Since this method should only be used in symmetric ciphers //(where the enc and dec keys are the same), set it on both: setEncryptionCipherKey(cipherKey); setDecryptionCipherKey(cipherKey); }
这就会导致了,第一次启动程序shiro使用A密钥加密了cookie,第二次启动程序shiro重新生成了密钥B,当用户访问页面时,shiro会用密钥B去解密上一次用密钥A加密的cookie,导致解密失败,导致报错,所以这不影响用户登录操作(rememberMe失效罢了),所以这种异常只会在程序重启(shiro清除session)第一次打开页面的时候出现
解决办法:
既然每次重启都会重新生成一对密钥,那我们就手动设置一个加解密密钥,主动设置cipherkey!!xml配置方式
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode(‘6ZmI6I2j5Y+R5aSn5ZOlAA==‘)}"/> <property name="cookie" ref="rememberCookie"/> </bean>
Unable to execute 'doFinal' with cipher instance [javax.crypto.Cipher@4e025e0a]
标签:builds sso issue shiro block defaults tin read identity
原文地址:https://www.cnblogs.com/deityjian/p/10775656.html