當Spring使用基本身份驗證時,我遇到了與HTTP響應頭「Access-Control-Allow-Origin」相關的問題。當我手動進行身份驗證,如代碼波紋管(我使用REST):Spring Security,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
,你可以看到,「訪問 - Control-Allow-Origin「出現在響應中。 這裏的一切都很好。我可以在我的ajax調用中發現401錯誤。
但是,當是自動執行的認證,如波紋管的代碼:在
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
沒有「訪問控制允許來源」:
@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響應是響應
谷歌瀏覽器的控制檯顯示以下錯誤:
Origin null is not allowed by Access-Control-Allow-Origin
即使HTTP響應返回它(上面的響應),我的ajax調用不會返回401 Unauthorized錯誤,但會收到未知錯誤。
我發現對於所有瀏覽器,我需要HTTP響應中的「Access-Control-Allow-Origin」,否則它們會產生某種無聲錯誤,並且我的ajax調用將失敗(無法捕捉到401錯誤)。其實,JavaScript會默默地失敗。 XMLHttpRequest 不接受沒有「Access-Control-Allow-Origin」的HTTP響應。
如何讓Spring在HTTP響應中爲基本身份驗證注入此「Access-Control-Allow-Origin」?
這是我的Spring Security XML:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http create-session="stateless" entry-point-ref="authenticationEntryPoint">
<security:intercept-url pattern="/customer/**" />
<security:http-basic />
<security:custom-filter ref="basicAuthenticationFilter"
after="BASIC_AUTH_FILTER" />
</security:http>
<bean id="basicAuthenticationFilter"
class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationEntryPoint" ref="authenticationEntryPoint" />
</bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
<property name="realmName" value="teste.com" />
</bean>
<!-- It is responsible for validating the user's credentials -->
<security:authentication-manager alias="authenticationManager">
<!-- It is responsible for providing credential validation to the AuthenticationManager -->
<security:authentication-provider>
<security:password-encoder ref="passwordEncoder" />
<security:jdbc-user-service
data-source-ref="mySQLdataSource"
users-by-username-query="select username, password, enabled from usuario where username = ?"
authorities-by-username-query="select username, papel from autoridade where username = ?" />
</security:authentication-provider>
</security:authentication-manager>
<bean class="org.springframework.security.crypto.password.StandardPasswordEncoder"
id="passwordEncoder" />
</beans>
謝謝你。您的解決方案幫助 –
嗨,我想問你以下。我想知道是否有特定的東西來啓用CROSS請求+基本授權+ Spring Security。到目前爲止,我已經完成了設置Tomcat過濾器(我向頭添加授權)所需的一切,因爲它在沒有認證的情況下工作,所以我在ajax中執行我的請求,所以我想知道spring安全是否不會引起問題.....也許你有一些關於它的輸入 – MaatDeamon
Access-Control-Allow-Origin是前端地址。你可以設置「*」來允許所有。 – raonirenosto