spring Sping Boot 404错误处理默认行为

uhry853o  于 2023-06-21  发布在  Spring
关注(0)|答案(1)|浏览(148)

我有一个Sping Boot 应用程序,没有404/500/403等错误处理,只是一些模板放在/resources/templates/error/*. html中。您可以假设 * 被替换为特定的错误代码,如404.html。现在,根据我的理解,Sping Boot 足够聪明,可以去抓住其中一个,而不需要进一步的配置,这很棒。但是,如果您查看下面的404代码,同时为虚拟服务器和部署的服务器显示页面,在后者上它不会产生任何thymeleaf变量,即它们是空的。

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
  xmlns:th="http://www.thymeleaf.org"
  xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
  layout:decorate="~{layout}">
  <head>
     <title>Error</title>
  </head>
  <body>
   <div layout:fragment="content">
   <div class="container-fluid">
   <div class="header text-center">
    <h3 class="title" id="elementtitle" data-type="text" data-pk="1" data-url="/post">An 
    error occurred</h3>
   </div>
   <div class="row">
   <div class="col-md-6">
   <div class="card">
   <div class="card-header card-header-text card-header-primary">
    <div class="card-text">
      <h4 class="card-title">404 Not Found</h4>
    </div>
   </div>
   <div class="card-body">
     <p>The requested resource could not be found.<a th:href="'hidden for privacy 
    purposes' + ${path}"   title="Error contact">Hidden for privacy purposes</a></p>
      <div class="alert alert-info"> 
         Application: Application<br/>
         Path: [[${path}]]<br/>
         Message: [[${message}]]<br/>
         Previous URL: <data th:text="${#httpServletRequest.getHeader('Referer')}"/> 
          <br/>
         Username: <data sec:authentication="name"/><br/>
         Time: [[${timestamp}]]
      </div>
     </div>
  </div>
 </div>
</div>
</div>
</div>
</body>
</html>

正如我已经提到的,所有的thymeleaf变量在部署的服务器上都是空的,而在虚拟服务器(localhost)上就可以了。有没有更有经验的人能告诉我为什么会发生这种行为。我的下一步是实现逻辑来处理服务器错误,但我只是好奇为什么会发生这种情况,因为它不是你会发现在教程。
先谢谢你。

k97glaaz

k97glaaz1#

显然,当发生错误时,出于安全目的,可部署远程服务器上的Sping Boot 会从SecurityContextHolder中清除Authentication对象,因此,如果您需要在捕获/error后传播需要用户身份验证的页面,默认情况下将不可能。我所做的解决方法是1)创建一个持久的SecurityContextFilter,并为HttpServletRequest的preHandle和postHandle添加一个拦截,以基本上获取Authentication对象,将其存储在请求的另一个属性中,并在ErrorController中再次获取它并设置:

SecurityContextHolder.getContext().setAuthentication(retrievedAuthentication);

而且效果很好

相关问题