Spring 通过异常或 AOP 在即将到来的响应中引导添加 header
Spring Boot add header in forthcoming response by exception or AOP
如何在响应中添加header以避免中断正常的服务流程?我想在 OncePerRequestFilter 中添加此操作,并可能通过 AOP 或 Exception 添加 header。因为这对我原来的代码影响不大。
我的问题:
如果token过期了,请求的header中是哪个?我想刷新令牌并将新令牌添加到响应的 header 中。这个操作不会影响正常的服务逻辑,也就是说它也有正常的body by controller.
Assess-Token: "xxx"
Connection: Keep-Alive
{
// normal serivce response in body
}
现在,我只能在 body 中响应新刷新的令牌。对于该请求中的所有服务,该操作将被中断。像这样:
Connection: Keep-Alive
{
Assess-Token: "xxx" // normal service has been interrupted, only token
}
提前致谢。
因此,据我了解您需要以下内容 - 如果传入的访问令牌已过期,您希望重新颁发它并将其发回给客户端,但响应的正文不得受到影响。如果是这种情况,请让我帮忙,但首先:您的请求必须包含刷新令牌和访问令牌。好吧,从技术上讲,如果访问令牌过期而没有刷新令牌检查,您可以重新发布访问令牌,但这显然 真的非常不安全 。这只是一个注释:)
那么,关于java servlet API,为什么不使用简单的HttpServletResponse#setHeader()呢?或者另一个选择是利用
Spring ResponseEntity class。例如:
@PostMapping
public void apiMethod(@RequestBody LegalEntity legalEntity, HttpServletResponse response) {
// TODO: 10.09.2021 ship refresh token along with access token
response.setHeader(HttpHeaders.AUTHORIZATION, "Bearer ...");
}
或者例如这个:
@PostMapping
public ResponseEntity<Void> apiMethod(@RequestBody LegalEntity legalEntity, HttpServletResponse response) {
// TODO: 10.09.2021 ship refresh token along with access token
return ResponseEntity.ok().header(HttpHeaders.AUTHORIZATION, "Bearer ..").build();
}
另一种情况是,如果您想从控制器资源中完全提取此逻辑。好吧,这在技术上可以通过 HandlerInterceptor.
的方式来实现
仍然 从我的角度来看,在它到达 DispatcherServlet 之前执行与您的令牌相关的所有操作(重新发布、验证或其他)会很棒,我的意思是,在FilterChain.
例如,您正在寻找的方法是检查传递的令牌是否有效,如果它已过期,则尝试重新发布新的 - 将其提取到新的 Filter 中。更具体地说,Spring 安全性有几个预定义的抽象,例如 OncePerRequestFilter。这只是我的看法。
如您所见,有很多选择。最终的选择取决于你到底想要什么。希望我已经为您提供了进一步调查的方向,祝您有愉快的一天!
非常感谢@misha2048,他的回答很清楚很完整,给了我提示。
这里我把我的实现复制过来,希望大家解答
public class AuthTokenFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
// validation the token
} catch (RefreshTokenException e) {
response.addHeader("accessToken", e.getToken());
log.info("Refresh Token");
} catch (TokenException e) {
// deal token expired
return;
}
filterChain.doFilter(request, response);
}
如何在响应中添加header以避免中断正常的服务流程?我想在 OncePerRequestFilter 中添加此操作,并可能通过 AOP 或 Exception 添加 header。因为这对我原来的代码影响不大。
我的问题:
如果token过期了,请求的header中是哪个?我想刷新令牌并将新令牌添加到响应的 header 中。这个操作不会影响正常的服务逻辑,也就是说它也有正常的body by controller.
Assess-Token: "xxx"
Connection: Keep-Alive
{
// normal serivce response in body
}
现在,我只能在 body 中响应新刷新的令牌。对于该请求中的所有服务,该操作将被中断。像这样:
Connection: Keep-Alive
{
Assess-Token: "xxx" // normal service has been interrupted, only token
}
提前致谢。
因此,据我了解您需要以下内容 - 如果传入的访问令牌已过期,您希望重新颁发它并将其发回给客户端,但响应的正文不得受到影响。如果是这种情况,请让我帮忙,但首先:您的请求必须包含刷新令牌和访问令牌。好吧,从技术上讲,如果访问令牌过期而没有刷新令牌检查,您可以重新发布访问令牌,但这显然 真的非常不安全 。这只是一个注释:)
那么,关于java servlet API,为什么不使用简单的HttpServletResponse#setHeader()呢?或者另一个选择是利用 Spring ResponseEntity class。例如:
@PostMapping
public void apiMethod(@RequestBody LegalEntity legalEntity, HttpServletResponse response) {
// TODO: 10.09.2021 ship refresh token along with access token
response.setHeader(HttpHeaders.AUTHORIZATION, "Bearer ...");
}
或者例如这个:
@PostMapping
public ResponseEntity<Void> apiMethod(@RequestBody LegalEntity legalEntity, HttpServletResponse response) {
// TODO: 10.09.2021 ship refresh token along with access token
return ResponseEntity.ok().header(HttpHeaders.AUTHORIZATION, "Bearer ..").build();
}
另一种情况是,如果您想从控制器资源中完全提取此逻辑。好吧,这在技术上可以通过 HandlerInterceptor.
的方式来实现仍然 从我的角度来看,在它到达 DispatcherServlet 之前执行与您的令牌相关的所有操作(重新发布、验证或其他)会很棒,我的意思是,在FilterChain.
例如,您正在寻找的方法是检查传递的令牌是否有效,如果它已过期,则尝试重新发布新的 - 将其提取到新的 Filter 中。更具体地说,Spring 安全性有几个预定义的抽象,例如 OncePerRequestFilter。这只是我的看法。
如您所见,有很多选择。最终的选择取决于你到底想要什么。希望我已经为您提供了进一步调查的方向,祝您有愉快的一天!
非常感谢@misha2048,他的回答很清楚很完整,给了我提示。
这里我把我的实现复制过来,希望大家解答
public class AuthTokenFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
// validation the token
} catch (RefreshTokenException e) {
response.addHeader("accessToken", e.getToken());
log.info("Refresh Token");
} catch (TokenException e) {
// deal token expired
return;
}
filterChain.doFilter(request, response);
}