我不确定我是否理解正确。我也有一个问题,将带有 json 的正确错误消息发送回客户端。我已经编写了所有(过滤器和提供者)自定义,因为我通过 HTTPHeaderFields 进行身份验证。
错误处理和将正确的消息发送回客户端一直是最大的问题。简要概述如下:
起初我创建了自定义 delegatingAuthenticationEntryPoint 和 AccesssDeniedHandler。
安全配置片段
...
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
// IMPORTANT: Add Filter after "ExceptionTranslation".
// If not AuthenticationException from Custom Filter or Custom Provider
// will not be catched by AuthenticationEntryPoint.
.addFilterAfter(httpClientFilter(), ExceptionTranslationFilter.class)
.exceptionHandling()
// catch AuthenticationExeption and SecureToken with authenticated=false
.authenticationEntryPoint(delegatingAuthenticationEntryPoint())
// catch PermissionDenied Exeption e.g. missing in authorizeRequests()
.accessDeniedHandler(new ClientRestAccessDeniedHandler())
.and()
...
ClientRestAccessDeniedHandler 看起来像这样
public class ClientRestAccessDeniedHandler implements AccessDeniedHandler{
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
final Logger logger = Logger.getLogger(ClientRestAccessDeniedHandler.class);
if(logger.isDebugEnabled())
logger.debug("Requered Role for this request is missing!");
HTTPAuthenticationErrorSender.sendResponse(request, response,
SecurityContextHolder.getContext().getAuthentication());
}
}
CustomDelegationEntriyPoint 看起来非常相似。两者都调用 HTTPAuthenticationErrorSender。它将发送由低级东西生成的 HttpResponse :-)。
public final class HTTPAuthenticationErrorSender {
public static void sendResponse(HttpServletRequest request, HttpServletResponse response, Authentication token)
throws JsonGenerationException, JsonMappingException, IOException{
final Logger logger = Logger.getLogger(HTTPAuthenticationErrorSender.class);
if(!(token instanceof HTTPRestSecureToken)){
if (token != null){
response.sendError(403, "No valide AuthenticationToken found. Token instance of: "+token.getClass().toString());
if(logger.isDebugEnabled())
logger.debug("Send default HTTP Response 403. No HTTPRestSecureToken found. "
+ "Token is instance of: "+token.getClass().getName());
}
else {
response.sendError(403, "No valide AuthenticationToken found. Token is null");
if(logger.isDebugEnabled())
logger.debug("Send default HTTP Response 403. No HTTPRestSecureToken found. "
+ "Token is null");
}
return;
}
HTTPRestSecureToken restToken = (HTTPRestSecureToken) token;
ObjectMapper mapper = new ObjectMapper();
AuthenticationErrorResponse authErrorResponse =
new AuthenticationErrorResponse(restToken.getAuthStatus().getErrorCode(),restToken.getAuthStatus().getDescription());
String content = mapper.writeValueAsString(authErrorResponse);
HTTPRestPrincipal principal = (HTTPRestPrincipal) token.getPrincipal();
if(logger.isDebugEnabled()){
logger.debug("AccessDenied for request: ["+principal.getFullURI()+"] clientID: ["+principal.getClientID()
+ "] loginMail: ["+principal.getLoginMail()+"]");
logger.debug("Send following json response: "+content);
}
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().print(content);
}
}
为了发送正确的信息,我在我的自定义 SecureToken 中跟踪状态信息。令牌将运行 throw 安全链过滤器和提供程序,并将填充信息。
是的,我会说这对于像这样的常见问题来说并不是很小。但我找不到其他方法。默认实现。对我的情况不够详细。
我希望它会对您有所帮助或推动您朝着正确的方向前进。