【问题标题】:How to override the response body of AuthenticationFailure using AbstractPreAuthenticatedProcessingFilter?如何使用 AbstractPreAuthenticatedProcessingFilter 覆盖 AuthenticationFailure 的响应正文?
【发布时间】:2020-11-06 09:23:44
【问题描述】:

我正在使用自定义过滤器来发出请求身份验证。配置AutheticationFailureHandler,我想放置消息错误内容,但它附加到现有的默认内容,我的目标是放在同一个正文上或只是一个新的。

处理程序实现:

 protected void configure(HttpSecurity httpSecurity) throws Exception {
APIKeyAuthFilter apiKeyAuthFilter = new APIKeyAuthFilter(HEADER_USER_AGENT, HEADER_APIKEY);

apiKeyAuthFilter.setAuthenticationFailureHandler((request, response, exception) -> {
                if(exception.getMessage().equals(MESSAGE_USER_AGENT_NOT_FOUND)) {
                    Map<String, Object> data = new HashMap<>();
                    data.put("message",MESSAGE_USER_AGENT_NOT_FOUND);
                    response.getOutputStream()
                            .println(objectMapper.writeValueAsString(data));
                }
            });
}

响应正文:

{
    "message": "User-Agent not found."
}
{
    "timestamp": "2020-07-16T16:26:59.438+0000",
    "status": 403,
    "error": "Forbidden",
    "message": "Access Denied",
    "path": "/api"
}

就像节目一样,这将返回两个 JSON 内容。我如何只设置一个或附加到存在?

完整代码:

public class APIKeyAuthFilter extends AbstractPreAuthenticatedProcessingFilter {

    private String userAgentRequestHeader;
    private String apiKeyRequestHeader;

    public APIKeyAuthFilter(String userAgentRequestHeader, String apiKeyRequestHeader) {
        this.userAgentRequestHeader = userAgentRequestHeader;
        this.apiKeyRequestHeader = apiKeyRequestHeader;
    }

    @Override
    protected RequestAuthVo getPreAuthenticatedPrincipal(HttpServletRequest request) {
        String userAgent = request.getHeader(userAgentRequestHeader);
        String apiKey = request.getHeader(apiKeyRequestHeader);
        RequestAuthVo requestAuthVo = new RequestAuthVo(userAgent,apiKey);
        return requestAuthVo;
    }

    @Override
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
        return "N/A";
    }

}

配置:

        @Override
        @Order(2)
        protected void configure(HttpSecurity httpSecurity) throws Exception {
                APIKeyAuthFilter apiKeyAuthFilter = new APIKeyAuthFilter(HEADER_USER_AGENT, HEADER_APIKEY);

            apiKeyAuthFilter.setAuthenticationManager(authentication -> {
                RequestAuthVo requestAuthVo = (RequestAuthVo) authentication.getPrincipal();

                if (!mapAuths.containsKey(requestAuthVo.getUserAgent())) {
                    throw new UserAgentNotFoundException(MESSAGE_USER_AGENT_NOT_FOUND);
                }

                if(mapAuths.containsKey(requestAuthVo.getUserAgent()) && mapAuths.get(requestAuthVo.getUserAgent()).equals(requestAuthVo.getApiKey())) {
                    authentication.setAuthenticated(true);
                    return authentication;
                }

                return authentication;
            });

            ObjectMapper objectMapper = new ObjectMapper();

 apiKeyAuthFilter.setAuthenticationFailureHandler((request, response, exception) -> {
                    if(exception.getMessage().equals(MESSAGE_USER_AGENT_NOT_FOUND)) {
                        Map<String, Object> data = new HashMap<>();
                        data.put("message",MESSAGE_USER_AGENT_NOT_FOUND);
                        response.getOutputStream()
                                .println(objectMapper.writeValueAsString(data));
                    }
                });

            httpSecurity.antMatcher("/**").
                    csrf().disable().
                    sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).
                    and()
                    .addFilter(apiKeyAuthFilter).authorizeRequests().anyRequest().authenticated();
        }

    }

【问题讨论】:

  • 你能用response.sendError(403, objectMapper.writeValueAsString(data)) 替换response.getOutputStream().println 看看吗?您还可以添加configure 的其余部分以查看您的APIKeyAuthFilter 插入的位置吗?
  • response.sendError(403, objectMapper.writeValueAsString(data))。响应正文只是:1
  • @KavithakaranKanapathippillai 我用configure 方法编辑过。

标签: java spring spring-security spring-cloud-security


【解决方案1】:

你可以试试这个吗?

    apiKeyAuthFilter.setAuthenticationFailureHandler(
            (request, response, exception) -> {
        if(exception.getMessage().equals(MESSAGE_USER_AGENT_NOT_FOUND)) {
            Map<String, Object> data = new HashMap<>();
            data.put("message",MESSAGE_USER_AGENT_NOT_FOUND);
            request.setAttribute("AGENT_NOT_FOUND", 
                                 objectMapper.writeValueAsString(data));
        }
    });

    http.exceptionHandling()
      .authenticationEntryPoint((request, response, e) ->
      {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        String value = request.getAttribute("AGENT_NOT_FOUND").toString();
        response.getWriter().write(value);
      });
    }

【讨论】:

  • 工作。但是这种方法有点冗长。
猜你喜欢
  • 2020-09-29
  • 2018-04-02
  • 2022-07-10
  • 2019-09-12
  • 1970-01-01
  • 2011-09-13
  • 2014-01-08
  • 1970-01-01
  • 2023-02-24
相关资源
最近更新 更多