Spring Security,REST基本身份validation问题

在使用Spring的基本认证时,我遇到了与HTTP响应头“Access-Control-Allow-Origin”相关的问题。 当我手动validation时,如下面的代码(我正在使用REST):

@RequestMapping(value = "/login", method = RequestMethod.POST, consumes = "application/json") @ResponseStatus(value = HttpStatus.OK) public void login(@RequestBody String body, HttpServletResponse response) throws IOException { try { User user = gson.fromJson(body, User.class); UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken( usuario.getUsername(), usuario.getPassword()); authenticationManager.authenticate(token); } catch (BadCredentialsException e) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } catch (Exception e) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } 

一切正常,我收到以下HTTP响应:

 HTTP/1.1 401 Unauthorized Server: Apache-Coyote/1.1 Access-Control-Allow-Origin: null Access-Control-Allow-Credentials: true Content-Type: text/html;charset=utf-8 Content-Length: 951 Date: Fri, 17 May 2013 19:14:36 GMT 

如您所见,响应中存在“Access-Control-Allow-Origin”。 这里一切都很好。 我可以在我的ajax调用中捕获401错误。

但是,当自动执行身份validation时,如下面的代码:

 @RequestMapping(value = "/name", method = RequestMethod.POST, consumes = "application/json") @PreAuthorize("hasRole('ROLE_CUSTOMER')") public @ResponseBody String getName(HttpServletResponse response) throws IOException { String json = null; try { User userSession = (User) SecurityContextHolder.getContext() .getAuthentication().getPrincipal(); Customer customer = customerDao.getNameByUsername(userSession.getUsername()); json = gson.toJson(customer); } catch (Exception e) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } return json; } 

HTTP响应是:

 HTTP/1.1 401 Unauthorized Server: Apache-Coyote/1.1 WWW-Authenticate: Basic realm="Spring Security Application" Content-Type: text/html;charset=utf-8 Content-Length: 981 Date: Fri, 17 May 2013 19:41:08 GMT 

响应中没有“Access-Control-Allow-Origin”

Google Chrome控制台显示以下错误:

 Origin null is not allowed by Access-Control-Allow-Origin 

我的ajax调用没有返回401 Unauthorized错误,即使HTTP响应返回它(上面的响应),我收到一个未知错误。

我发现对于所有浏览器,我需要在HTTP响应中使用“Access-Control-Allow-Origin”,否则它们会产生某种静默错误,我的ajax调用将失败(无法捕获401错误)。 实际上,javascript将无声地失败。 如果没有“Access-Control-Allow-Origin”,XMLHttpRequest不接受HTTP响应。

如何让Spring在HTTP响应中注入“Access-Control-Allow-Origin”以进行基本身份validation?

这是我的Spring Security xml:

                         

刚刚找到了自己的方式:

首先,我真的不记得为什么我把这一行放在这里,但它弄乱了我的代码:

  

其次,这个答案告诉我路径: 处理Spring Security中基本身份validation的未经授权的错误消息 。 我必须创建一个自定义身份validation入口点,以便发送Access-Control-Allow-Origin。

所以现在这是我的代码:

                           
 package com.test.util; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; public class PlainTextBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { response.addHeader("Access-Control-Allow-Origin", "null"); response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\""); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); PrintWriter writer = response.getWriter(); writer.println("HTTP Status " + HttpServletResponse.SC_UNAUTHORIZED + " - " + authException.getMessage()); } } 

我的http响应现在:

 HTTP/1.1 401 Unauthorized Server: Apache-Coyote/1.1 Access-Control-Allow-Origin: null WWW-Authenticate: Basic realm="test.com" Content-Length: 35 Date: Mon, 20 May 2013 20:05:03 GMT HTTP Status 401 - Bad credentials 

在更改之前,我收到此错误消息:

 OPTIONS http://localhost:8080/test/customer/name 200 (OK) jquery-1.8.2.min.js:2 XMLHttpRequest cannot load http://localhost:8080/test/customer/name. Origin null is not allowed by Access-Control-Allow-Origin. 

现在按照预期我得到了这个:

 OPTIONS http://localhost:8080/test/customer/name 200 (OK) jquery-1.8.2.min.js:2 POST http://localhost:8080/test/customer/name 401 (Unauthorized)