Spring Security - 记住我身份验证错误

2024-01-18

我们正在使用 Spring MVC,并遇到以下与 Remember Me 身份验证相关的问题:

  1. 用户在选中“记住我”的情况下登录,工作正常,perpetitive_login 表按预期更新
  2. 我们重新启动应用程序服务器,也许是在部署之后等
  3. 用户刷新页面,我们看到图 1 中的错误消息,用户被重定向到登录页面(没有看到错误)
  4. 尽管出现错误,permanent_login 条目令牌已更新(系列与刷新之前相同),spring Remember Me 令牌也保持不变。
  5. 用户第二次刷新页面,他们就像什么都没发生一样登录

图 1 -- 错误消息

Apr 24, 2014 9:29:15 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [workmarket] in context with path [] threw exception
java.lang.ClassCastException: org.springframework.security.web.firewall.FirewalledResponse cannot be cast to org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper
at org.springframework.security.web.context.HttpSessionSecurityContextRepository.saveContext(HttpSessionSecurityContextRepository.java:99)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:139)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:167)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)
at com.workmarket.web.authentication.CustomLinkedInLoginFilter.doFilter(CustomLinkedInLoginFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at com.workmarket.web.authentication.CustomLoginFilter.doFilter(CustomLoginFilter.java:100)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:86)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)

图 2——安全过滤器

<sec:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
<sec:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/>
<sec:custom-filter ref="customLoginFilter" position="FORM_LOGIN_FILTER"/>
<sec:custom-filter ref="customLinkedInLoginFilter" after="FORM_LOGIN_FILTER"/>
<sec:custom-filter ref="rememberMeFilter" position="REMEMBER_ME_FILTER"/>
<sec:custom-filter ref="switchUserProcessingFilter" position="SWITCH_USER_FILTER"/>
<sec:custom-filter ref="authenticatedUserInitializer" before="FILTER_SECURITY_INTERCEPTOR"/>
<sec:custom-filter ref="publicWorkRequestFilter" after="FILTER_SECURITY_INTERCEPTOR"/>
<sec:custom-filter ref="securityContextCleanupFilter" after="SESSION_MANAGEMENT_FILTER"/>
<sec:custom-filter ref="customLogoutFilter" position="LOGOUT_FILTER"/>

图 3 --“记住我”设置

<!-- Remember me -->
<bean id="rememberMeFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
    <constructor-arg index="0" ref="org.springframework.security.authenticationManager"/>
    <constructor-arg index="1" ref="rememberMeServices"/>
</bean>

<bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
    <constructor-arg index="0" value="[REMOVED]"/>
</bean>

<bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">
    <constructor-arg index="0" value="[REMOVED]"/>
    <constructor-arg index="1" ref="userDetailsService"/>
    <constructor-arg index="2" ref="persistentTokenRepository"/>
</bean>

Versions

  1. spring 框架 -- 3.2.4.RELEASE
  2. 春季安全——3.1.0.RELEASE
  3. spring-security-saml2-core -- 1.0.0.RC2
  4. opensaml -- 2.5.3

======更新======

我们发现,删除这两个与 SAML 相关的过滤器可以解决此问题,但是我们确实需要它们才能工作......

<sec:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
<sec:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/>

======更新2======

samlFilter 定义的详细信息。

<bean id="samlFilter" class="org.springframework.security.web.FilterChainProxy">
  <security:filter-chain-map request-matcher="ant">
  <security:filter-chain pattern="/saml/login/**" filters="samlEntryPoint"/>
  <security:filter-chain pattern="/saml/SSO/**" filters="samlWebSSOProcessingFilter"/>
  </security:filter-chain-map>
</bean>

<bean id="samlEntryPoint" class="org.springframework.security.saml.SAMLEntryPoint">
  <property name="defaultProfileOptions">
    <bean class="org.springframework.security.saml.websso.WebSSOProfileOptions">
      <property name="includeScoping" value="false"/>
    </bean>
  </property>
</bean>

<bean id="samlWebSSOProcessingFilter" class="org.springframework.security.saml.SAMLProcessingFilter">
  <property name="authenticationManager" ref="samlAuthenticationManager"/>
  <property name="authenticationSuccessHandler">
    <bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
      <property name="defaultTargetUrl" value="/"/>
    </bean>
  </property>
</bean>

提前致谢。


这是由于在 SecurityContextPersistenceFilter 之后使用 FilterChainProxy 造成的。具体来说,FilterChainProxy 的 HttpFirewall 正在用不再实现 SavedRequest 的 DefaultHttpFirewall 替换 HttpServletResponse。为了解决这个问题,您可以将自定义 HttpFirewall 注入到 samlFilter FilterChainProxy 中,该代理返回传递给它的相同 HttpServletResponse。例如:

public class DoNothingHttpFirewall implements HttpFirewall {

    public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException {
        return new MyFirewalledRequest(request);
    }

    public HttpServletResponse getFirewalledResponse(HttpServletResponse response) {
        return response;
    }

    private static class MyFirewalledRequest extends FirewalledRequest {
         MyFirewalledRequest(HttpServletRequest r) {
             super(r);
         }
         public void reset() {}
    }
}

然后您可以使用以下方式连接它:

<bean id="samlFilter" class="org.springframework.security.web.FilterChainProxy">
  <security:filter-chain-map request-matcher="ant">
    <security:filter-chain pattern="/saml/login/**" filters="samlEntryPoint"/>
    <security:filter-chain pattern="/saml/SSO/**" filters="samlWebSSOProcessingFilter"/>
  </security:filter-chain-map>
  <property name="firewall">
    <bean class="DoNothingHttpFirewall"/>
  </property>
</bean>

我已经记录了一张票,以便将来使这项工作透明化https://jira.spring.io/browse/SEC-2578 https://jira.spring.io/browse/SEC-2578

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Security - 记住我身份验证错误 的相关文章

随机推荐

  • 使用matlab配色方案将float转换为RGB

    例如 如果我有一个浮动0 568 浮动保证是0 gt 1 有没有办法将其转换为 RGB 值 双精度 1 0 1 0 1 0 or int 255 255 255 在当前的 matlab 配色方案 即正常 热 HSV 等 下 你可以试试这个
  • Intel x86 - 中断服务例程责任

    我没有真正意义上的问题 但我会尽力澄清内容问题 假设我们有一个微内核 PC Intel x86 32 位保护模式 中断描述符表 IDT and 中断服务程序 ISR 对于每个CPU异常 ISR 被成功调用 例如Division by Zer
  • 从 C 矩阵到现代 OpenGL 中的纹理?

    Problem 我正在尝试使用 OpenGL 用 C 编写一个简单的程序 这将允许 绘制 2D C 数组 int 32 位整数 根据调色板 目前 我还没有做到这一点 还很远 我正在学习如何将 32 位有符号整数数组发送到 GPU 并以某种方
  • {{ }} 和 {!! 之间有什么区别? !!} 在 Laravel Blade 文件中?

    在laravel框架中我们可以使用blade在html文件中添加PHP代码 我们正在使用两者 and Laravel 的 Blade 文件中的语法 它们之间有什么区别 Blade 语句通过PHP的htmlentities函数自动发送 以防止
  • 制作 PIE 对象时,不能使用针对符号“G8”的重定位 R_X86_64_32;使用-fPIE重新编译

    我正在尝试将 lambda 表达式从 schema 编译为 llvm ir 但在处理与位置无关的代码时遇到了问题 source lambda x display x target bunch of declares define SObj
  • 更新Map字段-Flutter

    如何更新 isVerified Boolean 字段的数据 个人信息是地图包含地址 然后经过验证 更新isVerified 您必须执行以下操作 Firestore instance collection collection Name do
  • 我们可以在 Spring Boot 中使用多个 kafka 模板吗?

    在我的 spring boot kafka 发布者应用程序中 我想提供对以 String json 或字节格式发布消息的支持 因为我想同时提供对 json 和 avro 的支持 但是 Spring Boot 中的 Kafka 模板让我们只定
  • 有没有办法在 R 中为 Word 制作漂亮的表格?

    我问我的问题 这是我最后的希望 我必须用 Word 制作一份报告 我从事 R Markdown 工作 必须生成许多表格 我希望我的桌子很漂亮 但我尝试过的一切 pander KableExtra flextable 不工作 我的结果来自co
  • 尝试使用 Angular 中的 Google People API 获取生日和性别

    我已经花了几个小时尝试这样做 但我永远无法获得我想要获得的数据 我需要以其他方式提出请求吗 这是我的代码 doGoogleLogin return new Promise
  • 是否有 jquery 下拉年份选择器 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有一个 jQuery 插件可以自动创建下拉年份选择器 这是一个 选择 元素 填充了从当前开始并追溯
  • 如何使用 jquery/javascript 在 safari 中复制到剪贴板?

    我研究了一堆答案和文章 它们展示了如何通过 jquery 在按钮单击时复制文本 但没有一个对我有用 我通过 ajax 将一个值附加到 DOM 中 我希望通过单击按钮来复制该值 所有这些解决方案都可以在 chrome 上运行 如果使用 jsf
  • 放弃更改而不从历史记录中删除

    有一个提交不起作用 所以我想放弃它而不将其从历史记录中删除 我已经从早期的修订版中更新并提交 从而创建了一个新的头 我没有分支 我不想要分支 我只想简单地继续使用新的头 就像它原来的样子 没有什么花哨的 没有合并 没有担心 只是继续忘记前一
  • Alexa Skills Kit 输入的“包罗万象”不符合既定意图

    我正在构建一个 Alexa 应用程序 它需要能够处理问题的答案 我有一个SkipIntent具有跳过问题的示例话语的意图 我想建立一个AnswerIntent它可以获取任何答案 并根据正确答案对其进行处理 我尝试使用Amazon LITER
  • 如何在 Java 中检测 SQL 表是否存在?

    如何在 Java 中检测给定 SQL 数据库中是否存在某个表 您可以使用DatabaseMetaData getTables http java sun com j2se 1 5 0 docs api java sql DatabaseMe
  • 何时不在 CakePhp 2.x 中使用可包含行为

    在将 Containable Behaviour 添加到我的各种模型类中几次后 我决定简单地将该行放入 AppModel 中 从而使每个模型都可包含 这让我想知道 是否有任何情况下 特定模型具有可控制行为是不理想的或适得其反的 我想说太少了
  • 更改JLabel的字体

    如何更改JLabel的字体 我尝试这样做但没有成功 JLabel nadpis new JLabel nadpis setFont new Font Papyrus Font ITALIC 100 nadpis setText hi 只是大
  • 将 BasedOn 属性与在不同字典中定义的 Style 结合使用

    我正在开发的应用程序有 2 个 ResourceDictionary DefaultStyles xaml 和 CustomStyles xaml CustomStyles 字典中的样式是否可能使用其他字典中定义的基本样式 默认样式 xam
  • 在一个查询中计算 MySQL 中的多行数

    我目前有一个表 其中存储了多个项目的大量统计信息 例如查看 下载 购买等 要获取每个项目的单个操作计数 我可以使用以下查询 SELECT COUNT FROM stats WHERE operation view GROUP BY item
  • pandas groupby 列并检查组是否满足多个条件

    我有一个如下所示的 DataFrame X Y Date are equal 0 50 0 10 0 2018 08 19 False 1 NaN 10 0 2018 08 19 False 2 NaN 50 0 2018 08 19 Tr
  • Spring Security - 记住我身份验证错误

    我们正在使用 Spring MVC 并遇到以下与 Remember Me 身份验证相关的问题 用户在选中 记住我 的情况下登录 工作正常 perpetitive login 表按预期更新 我们重新启动应用程序服务器 也许是在部署之后等 用户