当前位置: 首页 > 面试题库 >

Spring SecurityContext在错误页面上返回空身份验证

田普松
2023-03-14
问题内容

我正在尝试为403(访问被拒绝)和500(内部服务器错误)之类的错误编写一个自定义错误页面。它们将从Velocity模板呈现,并使用用户的语言环境翻译所有消息。身份验证和区域设置解析在应用程序中运行良好。

我将web.xml中的位置设置为所需的页面,并在webmvc-context.xml中通过添加了Requet-to-view控制器。

我遇到的问题是 SecurityContextHolder.getContext()。getAuthentication()
在错误页面视图中返回null。查看日志,我看到了:

06.10 14:42:26 DEBUG - context.HttpSessionSecurityContextRepository(HttpSessionSecurityContextRepository.java:351) -  - SecurityContext stored to HttpSession: 'org.springframework.security.core.context.SecurityContextImpl@ece7b0b7: Authentication: ...
06.10 14:42:26 DEBUG - context.SecurityContextPersistenceFilter(SecurityContextPersistenceFilter.java:89) -  - SecurityContextHolder now cleared, as request processing completed
06.10 14:42:26 DEBUG - servlet.DispatcherServlet(DispatcherServlet.java:691) -  - DispatcherServlet with name 'foo' processing GET request for [/foo/app/error/403.html]

因此,无论是Spring还是Tomcat,都将重定向到错误页面,请求gest最终确定,从而清除了上下文。并且新的“请求”没有经过Spring
Security过滤器,因此没有还原上下文。

通常的方法不起作用,但是似乎身份验证信息在会话中的某处,这也是因为AbstractTemplateView记录以下内容:

Exposing session attribute 'SPRING_SECURITY_CONTEXT' with value [org.springframework.security.core.context.SecurityContextImpl@edfbd958: Authentication: org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken@edfbd958...

我如何正确获取正常页面和错误页面的行为?


问题答案:

您遇到的问题是,ExceptionTranslationFilter哪个将异常转换为错误页面,而SecurityContextPersistenceFilter后者将身份验证从中提取出来SecurityContextRepository并将其放入中SecurityContextHolder。请求完成后,SecurityContextPersistenceFilter会将信息从中取出SecurityContextHolder

清除的原因SecurityContextHolder是,SecurityContextHolder通常是本地线程,如果servlet容器要重用线程(大多数这样做),它们可能会不小心将这些凭据提供给其他人。

通常,ExceptionTranslationFilter过滤器是最外面的过滤器,以避免发生任何异常无法转换的风险。

最好的选择是编写一个ExceptionTranslationFilter接受SecurityContextRepository(通常是您提到的HTTP会话)并Authentication通过SecurityContextRepository和而不是通过提供访问的自定义SecurityContextHolder。请记住,Authentication如果用户未登录,则仍然为null。



 类似资料:
  • 问题内容: 以下是我从GoLang获得的MongoDB连接拨号。但是它返回一个紧急消息“ SASL身份验证步骤服务器返回错误:身份验证失败。 ”。我的用户名,密码,hostAddrs和dbName是正确的。我在这里想念什么? 问题答案: 我遇到类似的错误并添加了参数,并且在我们连接到远程MongoDB时可以正常工作 在您的代码中使用以下类似格式:

  • 使用GitHub从命令行(通过https而不是ssh)启动一个push或任何其他调用用户名和密码的操作不仅会失败,而且会返回 我没有地址。密码和用户名正确。 我知道我可以切换到SSH并使用密钥,但这并不能回答为什么身份验证在HTTPS上失败。

  • 问题内容: 我正在尝试使用mgo库从Go连接到远程MongoDB数据库(Mongolab),但出现错误。这是我的代码 我怎样才能解决这个问题?当然,我在代码中使用星号和密码代替星号。 问题答案: 请检查是否为Mongolab数据库实例添加了用户(如果数据库名称为,则为https://mongolab.com/databases/catalog#users),因为默认情况下,用户列表为空(帐户use

  • cluster=hfactory.getOrCreateCluster(“test cluster”,“localhost:9160”,凭据); 但不幸的是,它给了我一个错误: HFactory类型中的方法getOrCreateCluster(String,CassandraHostConfigurator,Map)不适用于参数(String,String,Map)

  • 我想在创建新用户时添加用户的DisplayName。当我尝试使用updateProfile方法时,它会发出以下警告 ///更新用户的配置文件数据。 @已弃用('将在版本2.0.0中删除。''改用updatePhotoURL和updateDisplayName。', 你怎么能避开这个?? flutter: User(显示名称:null,电子邮件:test1@gmail.com,emailVerifi

  • @将有效的打印信息发送到控制台,但不发送到页面 当我的字段有错误@Valid print info到控制台时,为什么不在第页? 字段hotelName上的对象formData中的字段错误:拒绝的值[];代码[Size.formData.hotelName, Size.hotelName, Size.java.lang.String, size];参数[org.springframework.con