【问题标题】:Unable to send "Unauthorized" in http header from Spring Boot filter无法从 Spring Boot 过滤器在 http 标头中发送“未授权”
【发布时间】:2017-12-25 15:21:44
【问题描述】:

我正在尝试使用Spring Boot 编写身份验证过滤器;其中我检查了一些 cookie,如果它存在于请求中,我想将请求标记为已授权,否则我想返回 401 标头以响应客户端调用我的服务。

下面是我在 Spring Boot 过滤器中使用的行:

((HttpServletResponse) res).sendError(HttpServletResponse.SC_UNAUTHORIZED, "User is not authenticated, so can not access IPT service.");

虽然当请求中没有 cookie 时,此行会在我的 Auth 过滤器中执行;在我的客户端代码中,当使用 response.headers 检查时,我没有看到标题 401 设置

我什至尝试过使用:

((HttpServletResponse) res).addHeader("401", "Unauthorized!");
return;

但是,没有运气!

我做错了吗?

编辑#1:

添加处理请求/响应的客户端代码:

fetch(FETCH_URL, {
  method: 'GET',
  dataType: 'json',
  credentials: 'include'

}).then(
  function(response) {
    if(response.status == 401) {
      console.log("----->", response);
      alert(response + " Redirect to login page!");
    }
  },
  function() {
    alert("Error!");
});

编辑#2:

当我尝试收到 Finnbar O'G 建议的错误消息时:

response.text().then((text) => { console.log("----->", text); });

我得到了整个 HTML:

<!doctype html>
<html lang="en">
  <head><title>HTTP Status 401 – Unauthorized</title>
    <style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}
    </style>
  </head>
  <body>
    <h1>HTTP Status 401 – Unauthorized</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Message</b> User is not authenticated, so can not access IPT service.</p><p><b>Description</b> The request has not been applied because it lacks valid authentication credentials for the target resource.</p><hr class="line" /><h3>Apache Tomcat/9.0.0.M22</h3>
  </body>
</html>

我怎样才能只从服务器获取我作为sendError 方法的第二个参数添加的消息?

好吧,这是我的过滤器代码:

@Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
    LOGGER.info("****************** Inside Auth Filter ******************");
    boolean success = process(req); // Checks if auth cookie is set in request

    if (success) {
        filterChain.doFilter(req, res);
    } else {
        // ((HttpServletResponse) res).addHeader("401", "Unauthorized!");
        ((HttpServletResponse) res).sendError(HttpServletResponse.SC_UNAUTHORIZED, "User is not authenticated, so can not access IPT service.");
    }
    }

谢谢

【问题讨论】:

  • 显示您的过滤器代码和过滤器配置。

标签: javascript spring reactjs servlets spring-boot


【解决方案1】:

response.headers 将只包含设置的 HTTP 标头,sendError 正在发送一个完整的 HTTP 响应,其中包括标头、响应正文和状态。 response.status 将是 401 错误,response.body 将是消息“用户未通过身份验证,因此无法访问 IPT 服务。”。您应该在您的客户端代码中检查这些。

编辑:

由于您使用 fetch(),您可以使用 response.text() 以纯 tet 形式访问响应正文。这将返回一个 Promise,在您可以使用响应正文之前必须先解决该 Promise:例如

fetch(FETCH_URL, {
  method: 'GET',
  dataType: 'json',
  credentials: 'include'

}).then(
  function(response) {
    if(response.status == 401) {
      response.text().then((text) => { console.log("----->", text); });
      alert(response + " Redirect to login page!");
    }
  },
  function() {
    alert("Error!");
});

关于使用 fetch 的 MDN 文档对于理解如何处理响应很有帮助。

【讨论】:

  • 谢谢!我可以在 response.status 中获得错误代码为 401。但是,我无法在 response.body 中获得消息.....
  • 您能否发布处理您的请求和响应的客户端代码?您可能需要参考在您的客户端代码中生成的特定响应实现的 API 参考。你可能使用 XHR 还是 fetch?
  • 在我的问题中添加,我正在使用 fetch。
  • 检查我上面更新的答案,我认为这将使您的响应正文作为您可以控制台.log 的文本。
  • 哎呀.. 它打印整个 HTML,如我上面更新的问题所示
【解决方案2】:

我已使用以下流程完成此操作:

  1. 创建一个类并实现过滤器接口
  2. 使用@Configuration 将类标记为配置类
  3. 如果存在多个过滤器,则可以设置过滤器链的顺序@Oder(orderNo)
  4. 实现doFilter方法
  5. 检查 Http Header 值用户名/密码/认证码等
  6. 如果身份验证信息不正确,则返回错误

示例: import java.io.IOException;

导入 javax.servlet.Filter; 导入 javax.servlet.FilterChain; 导入 javax.servlet.ServletException; 导入 javax.servlet.ServletRequest; 导入 javax.servlet.ServletResponse; 导入 javax.servlet.http.HttpServletRequest; 导入 javax.servlet.http.HttpServletResponse;

导入 org.springframework.core.annotation.Order; 导入 org.springframework.stereotype.Component;

@组件 @订单(1) 公共类 ReqResFilter 实现过滤器 {

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
            
    if(!req.getHeader("Authorization").equals("12345666")) {
        res.sendError(401, "Invalid Authorization code");
    }
    else {
        chain.doFilter(request, response);
    }
}

}

【讨论】:

    猜你喜欢
    • 2021-05-28
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    • 1970-01-01
    • 2017-01-17
    • 2015-12-25
    • 2017-12-04
    相关资源
    最近更新 更多