使用带有 Shiro 的 RememberMe 令牌标记不匹配
Posted
技术标签:
【中文标题】使用带有 Shiro 的 RememberMe 令牌标记不匹配【英文标题】:Tag Mismatch using RememberMe token with Shiro 【发布时间】:2021-06-29 14:40:39 【问题描述】:在我网站的几个版本之前,我开始在我的错误日志中一遍又一遍地收到以下警告。
Message:
Delegate RememberMeManager instance of type [org.apache.shiro.web.mgt.CookieRememberMeManager] threw an exception during getRememberedPrincipals().
Exception:
org.apache.shiro.crypto.CryptoException: Unable to execute 'doFinal' with cipher instance [Cipher.AES/GCM/NoPadding, mode: decryption, algorithm from: SunJCE].
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:613)
at org.apache.shiro.mgt.DefaultSecurityManager.resolvePrincipals(DefaultSecurityManager.java:501)
at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:347)
at org.apache.shiro.subject.Subject$Builder.buildSubject(Subject.java:845)
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.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
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.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
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.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:141)
at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
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 ch.qos.logback.classic.helpers.MDCInsertingServletFilter.doFilter(MDCInsertingServletFilter.java:49)
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:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
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:1590)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: javax.crypto.AEADBadTagException: Tag mismatch!
at java.base/com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:623)
at java.base/com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1118)
at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1055)
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:855)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2207)
at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:459)
... 51 common frames omitted
在此期间,我没有更改我的 RememberMe 令牌(我知道),例如我的密码密钥。我确实尝试使我的支持库保持最新,因此可能是其中一个升级导致了这种情况,但我没有真正的想法。奇怪的是,我的网站似乎没有受到影响,没有人报告说 RememberMe 令牌不记得它们的问题。我很想知道发生了什么,这样我就可以摆脱这些警告,再次对我的网站感到安全。非常感谢任何帮助。以下是我目前正在使用的一些相关的 3rd-party 包...
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
<version>2.4.1</version>
</dependency>
更新:
我应该说我的Remember Cookie是通过以下代码配置的:
@Configuration
public class SpringBeanConfigurer
@Bean
public org.apache.shiro.mgt.SecurityManager securityManager()
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(<myRealm>;
CookieRememberMeManager rmm = new CookieRememberMeManager();
rmm.setCipherKey(Base64.decode(<cipher key string>));
securityManager.setRememberMeManager(rmm);
return securityManager;
【问题讨论】:
【参考方案1】:我会做一些猜测假设。
该消息已记录,但请求没有失败? 您最近从 Shiro如果是这样,这听起来可能与 CVE-2019-12422 有关 因此,默认的记住我加密格式已更改。 虽然我们建议您不要恢复到以前的格式,但在本期中有关于如何执行此操作的说明:https://issues.apache.org/jira/browse/SHIRO-730
【讨论】:
是的,这正是我所看到的。如前所述,异常被记录为警告,由于没有人抱怨该站点,我假设所有请求都在继续。所以,我当然可以恢复,但由于不建议这样做,我能做些什么来让它按照现在的预期方式工作?没有说明。我没有使用任何配置文件,所以使用默认值。 我已更新显示我如何配置我的 CookieRememberMeManager。 当用户在访问您的网站时显示“旧的”记住我的 cookie 时会出现警告。如果用户未登录,Shiro 将删除 cookie(指示浏览器将其删除),如果用户未登录(或下次登录),则发出新的一次。 一旦您的所有用户再次登录,您将不会再看到这些警告。如果您有成千上万的用户,并且您认为此日志垃圾邮件,您可以覆盖相关方法,并以不同方式管理它:github.com/apache/shiro/blob/master/core/src/main/java/org/… 啊啊,那么它只是一个等待游戏。 :) 它似乎确实放慢了速度。所以我的用户群正在慢慢更新,如果我理解正确,这些消息最终会消失。谢谢!!以上是关于使用带有 Shiro 的 RememberMe 令牌标记不匹配的主要内容,如果未能解决你的问题,请参考以下文章