Tôi sử dụng Spring Boot với Spring Security và Cors Support.Cách cấu hình CORS trong ứng dụng Spring Boot + Spring Security?
Nếu tôi thực hiện đoạn mã sau
url = 'http://localhost:5000/api/token'
xmlhttp = new XMLHttpRequest
xmlhttp.onreadystatechange = ->
if xmlhttp.readyState is 4
console.log xmlhttp.status
xmlhttp.open "GET", url, true
# xmlhttp.setRequestHeader "X-Requested-With", "XMLHttpRequest"
xmlhttp.setRequestHeader 'Authorization', 'Basic ' + btoa 'a:a'
do xmlhttp.send
tôi nhận được kết quả
200
một Nếu tôi thử nghiệm với các thông tin sai như
url = 'http://localhost:5000/api/token'
xmlhttp = new XMLHttpRequest
xmlhttp.onreadystatechange = ->
if xmlhttp.readyState is 4
console.log xmlhttp.status
xmlhttp.open "GET", url, true
# xmlhttp.setRequestHeader "X-Requested-With", "XMLHttpRequest"
xmlhttp.setRequestHeader 'Authorization', 'Basic ' + btoa 'a:aa'
do xmlhttp.send
thay vì nhận được 401 (đó là mã chuẩn để xác thực sai trong bảo mật mùa xuân) Tôi nhận được
0
với thông báo trình duyệt sau:
GET http://localhost:5000/api/token
XMLHttpRequest không thể tải http://localhost:5000. Không có tiêu đề 'Access-Control-Allow-Origin' xuất hiện trên tài nguyên được yêu cầu. Do đó, nguồn gốc 'http://localhost:3000' không được phép truy cập. Phản hồi có mã trạng thái HTTP 401.
Tôi đang phát triển mã front-end cần mã trạng thái http hữu ích từ các phản hồi của máy chủ để xử lý tình huống. Tôi cần một cái gì đó hữu ích hơn 0. Ngoài ra cơ thể phản ứng là trống rỗng. Tôi không biết nếu cấu hình của tôi là sai, hoặc đó là một lỗi phần mềm và tôi cũng không biết ở đâu, nếu đó là chromium (sử dụng Linux vòm) hoặc bảo mật mùa xuân.
My Xuân Config là:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@RestController
@RequestMapping("api")
public class Controller {
@RequestMapping("token")
@CrossOrigin
Map<String, String> token(HttpSession session) {
return Collections.singletonMap("token", session.getId());
}
}
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("a").password("a").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.anyRequest().authenticated()
.and().httpBasic();
}
}
Nếu tôi thử nghiệm với tất cả mọi thứ curl công trình hoàn hảo, tôi nghĩ rằng vì không CORS hỗ trợ cần thiết, nhưng tôi đã cố gắng để mô phỏng các CORS với yêu cầu OPTION và kết quả cũng ok.
$ curl -v localhost:5000/api/token -H "Authorization: Basic YTpha"
* Trying ::1...
* Connected to localhost (::1) port 5000 (#0)
> GET /api/token HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.48.0
> Accept: */*
> Authorization: Basic YTpha
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Access-Control-Allow-Origin: http://localhost:3000
< Access-Control-Allow-Methods: POST,GET,OPTIONS,DELETE
< Access-Control-Max-Age: 3600
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Origin,Accept,X-Requested- With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization
< x-auth-token: 58e4cca9-7719-46c8-9180-2fc16aec8dff
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 01 May 2016 16:15:44 GMT
<
* Connection #0 to host localhost left intact
{"token":"58e4cca9-7719-46c8-9180-2fc16aec8dff"}
và với các thông tin sai:
$ curl -v localhost:5000/api/token -H "Authorization: Basic YTp"
* Trying ::1...
* Connected to localhost (::1) port 5000 (#0)
> GET /api/token HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.48.0
> Accept: */*
> Authorization: Basic YTp
>
< HTTP/1.1 401 Unauthorized
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< WWW-Authenticate: Basic realm="Realm"
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 01 May 2016 16:16:15 GMT
<
* Connection #0 to host localhost left intact
{"timestamp":1462119375041,"status":401,"error":"Unauthorized","message":"Failed to decode basic authentication token","path":"/api/token"}
Edit: Để tránh hiểu lầm. Tôi sử dụng 1.3.3 Spring Boot. Bài đăng trên blog viết:
Hỗ trợ CORS sẽ có trong bản phát hành Spring Boot 1.3 sắp tới và đã có sẵn trong bản 1.3.0.BUILD-SNAPSHOT.
Sử dụng phương pháp điều khiển Cấu hình CORS với chú thích @CrossOrigin trong ứng dụng Khởi động mùa xuân của bạn không yêu cầu bất kỳ cấu hình cụ thể nào.
cấu hình toàn cầu CORS thể được định nghĩa bằng cách đăng ký một bean WebMvcConfigurer với một addCorsMappings tùy chỉnh (CorsRegistry) Phương pháp:
Tôi đã thêm mã sau đây để kích hoạt tính năng hỗ trợ CORS toàn cầu. thực sự tôi đã thử điều này trước đây nhưng kết quả là như nhau. Tôi đã thử lại lần nữa và kết quả là như nhau.
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
};
}
}
Ý tưởng, vấn đề xuất phát từ chuyển hướng giữa quá trình ủy quyền là một điều thú vị. làm cách nào tôi có thể thay đổi chuyển hướng sang bất kỳ tài nguyên nào để tránh xung đột này?
EDIT:
Tôi đoán tôi gần hơn với giải pháp. Tôi đã thử nghiệm với máy chủ nodejs của mình hỗ trợ cors mà không gặp sự cố bằng cách thêm Access-Control-Allow-Origin: * cho tất cả các yêu cầu.
Giống như Stefan Isele đã đề cập có vẻ như bảo mật mùa xuân chuyển hướng hoặc không thêm tiêu đề CORS vì vậy đó là lý do tại sao yêu cầu có vẻ bị hỏng. Vì vậy, trong khi bảo mật mùa xuân đang kiểm tra xác thực, nó phải thêm tiêu đề thích hợp.
Có ai biết cách làm như vậy không?
CHỈNH SỬA:
Tôi tìm thấy giải pháp thay thế, điều đó có vẻ xấu. Tôi đã bắt đầu một vấn đề github cho khởi động mùa xuân, nơi tôi mô tả cách giải quyết: https://github.com/spring-projects/spring-boot/issues/5834
https://stackoverflow.com/a/35040051/2884309 <- giải pháp này vẫn hoạt động trên spring-boot 1.5.6 –