如何使用 AbstractPreAuthenticatedProcessingFilter 覆盖 AuthenticationFailure 的响应主体?
How to override the response body of AuthenticationFailure using AbstractPreAuthenticatedProcessingFilter?
我正在使用自定义过滤器进行请求验证。配置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();
}
}
你能试试这个吗?
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);
});
}
我正在使用自定义过滤器进行请求验证。配置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();
}
}
你能试试这个吗?
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);
});
}