如何在自定义Spring security 3.0身份验证中正确处理异常?
我正在开发一个基于令牌的REST服务。当用户通过curl转到../rest/authenticate with the user and password时,获取一个有效令牌以使用整个API 当用户忘记在其他方法中插入用户名、密码或令牌时,就会出现我的问题,因为我没有按照自己的意愿处理身份验证异常 我可以处理异常,但是tomcat得到了响应并插入了一些我不期望的html 这是tomcat的典型响应。 有没有可能收到一个像200OK这样没有html代码的响应 现在,这是我的配置: AuthenticationProcessingFilter 决定url是否安全。如果必须对其进行安全保护,请调用身份验证管理器对其进行验证。如果收到身份验证异常,则调用AuthenticationEntryPoint如何在自定义Spring security 3.0身份验证中正确处理异常?,spring,rest,spring-mvc,spring-security,Spring,Rest,Spring Mvc,Spring Security,我正在开发一个基于令牌的REST服务。当用户通过curl转到../rest/authenticate with the user and password时,获取一个有效令牌以使用整个API 当用户忘记在其他方法中插入用户名、密码或令牌时,就会出现我的问题,因为我没有按照自己的意愿处理身份验证异常 我可以处理异常,但是tomcat得到了响应并插入了一些我不期望的html 这是tomcat的典型响应。 有没有可能收到一个像200OK这样没有html代码的响应 现在,这是我的配置: Authen
public class AuthenticationTokenProcessingFilter extends GenericFilterBean {
private final Collection<String> nonTokenAuthUrls = Lists.newArrayList("/rest","/rest/authenticate");
TokenAuthenticationManager tokenAuthenticationManager;
RestAuthenticationEntryPoint restAuthenticationEntryPoint;
public AuthenticationTokenProcessingFilter(TokenAuthenticationManager tokenAuthenticationManager, RestAuthenticationEntryPoint restAuthenticationEntryPoint) {
this.tokenAuthenticationManager = tokenAuthenticationManager;
this.restAuthenticationEntryPoint = restAuthenticationEntryPoint;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest)request;
HttpServletResponse httpResponse = (HttpServletResponse)response;
try{
if(!nonTokenAuthUrls.contains(httpRequest.getRequestURI())){ //Auth by token
String hash = httpRequest.getHeader("token");
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(hash, null);
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails((HttpServletRequest) request));
SecurityContextHolder.getContext().setAuthentication(tokenAuthenticationManager.authenticate(authentication));
}
response.reset();
chain.doFilter(request, response);
}catch(AuthenticationException authenticationException){
SecurityContextHolder.clearContext();
restAuthenticationEntryPoint.commence(httpRequest, httpResponse, authenticationException);
}
}
AuthenticationEntryPoint
这门课还可以。收到的代码是401未经授权的,但消息是在tomcat html中
公共类重新验证EntryPoint实现AuthenticationEntryPoint{
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException {
response.setContentType("application/json");
response.sendError( HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage() );
response.getOutputStream().println("{ \"error\": \"" + authenticationException.getMessage() + "\" }");
}
}
RestAccessDeniedHanler也不被调用。这很困难,因为有很多类需要实现
我查看了stackoverflow和其他网站中的一些帖子,我的方法是在AuthenticationProcessingFilter中捕获异常并手动调用AuthenticationEntryPoint。我决定这样做是因为我试图在applicationContext-security.xml中配置它,但没有成功
appliacionContext-security.xml
如何发送带有错误代码和消息的清晰响应?您可以使用web.xml中的错误页面截取Tomcat的错误页面。比如说,
<error-page>
<error-code>404</error-code>
<location>/404</location>
</error-page>
404
/404
现在,您可以使用RequestMapping将/404映射到一个页面,该页面返回您的JSON响应,而不包含任何HTML:
@RequestMapping(value = "/404", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE})
@ResponseBody
public ResponseEntity<ResponseStatus> handle404() {
HttpStatus status = null;
ResponseStatus responseStatus = new ResponseStatus("404", "Wrong path to resource.");
status = HttpStatus.NOT_FOUND;
ResponseEntity<ResponseStatus> response = new ResponseEntity<ResponseStatus>(responseStatus, status);
return response;
}
@RequestMapping(value=“/404”,method={RequestMethod.GET,RequestMethod.POST,RequestMethod.PUT,RequestMethod.DELETE})
@应答器
公共责任处理404(){
HttpStatus状态=空;
ResponseStatus ResponseStatus=新ResponseStatus(“404”,“资源路径错误”);
status=HttpStatus.NOT_FOUND;
ResponseEntity response=新的ResponseEntity(responseStatus,状态);
返回响应;
}
它只返回一个名为Response Status的JSON对象,其中包含一个错误代码和错误消息作为字段。我没有提到在我的应用程序中有两个http。一个用于dp/rest,无需web浏览器即可访问;另一个用于dp/rest,具有要使用web浏览器访问的视图(jsp页面)。这只能通过web.xml实现吗?因为在web.xml中我已经有404/错误/notfound.jsp。。有可能分离错误吗?如果您知道异常是什么,您可以在Spring中定义ExceptionHandler,以便在抛出异常时执行任何您想要的操作。这听起来像你要找的。如果您需要更多信息,请告诉我。。。但一个开始寻找的好地方是:
<error-page>
<error-code>404</error-code>
<location>/404</location>
</error-page>
@RequestMapping(value = "/404", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE})
@ResponseBody
public ResponseEntity<ResponseStatus> handle404() {
HttpStatus status = null;
ResponseStatus responseStatus = new ResponseStatus("404", "Wrong path to resource.");
status = HttpStatus.NOT_FOUND;
ResponseEntity<ResponseStatus> response = new ResponseEntity<ResponseStatus>(responseStatus, status);
return response;
}