[SPRING] 요청의 자격 증명 모드가 '포함'인 경우 응답의 헤더는 와일드 카드 '*'가 아니어야합니다.
SPRING요청의 자격 증명 모드가 '포함'인 경우 응답의 헤더는 와일드 카드 '*'가 아니어야합니다.
내 사용자 인증을 위해 Auth0을 사용하여 로그인 한 사용자 만 Spring (Boot) RestController에 액세스하도록 허용합니다. 이 시점에서 저는 사용자가 stompjs와 sockjs를 사용하여 Angular 2 클라이언트 (localhost : 4200)에서 Spring 서버 (localhost : 8081)로 메시지를 보낼 수있는 실시간 메시지 기능을 만들고 있습니다.
Stomp-client를 만들고 연결을 시작할 때 다음과 같은 콘솔 오류가 발생합니다 :
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:4200' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
이 문제를 연구 한 후에 동시에 originins = * 및 credentials = true 옵션을 설정할 수없는 것처럼 보입니다. WebSocketConfig에서 허용 된 출처를 클라이언트 도메인에 이미 설정 한 경우 어떻게 해결할 수 있습니까?
각도 2 성분
connect() {
var socket = new SockJS('http://localhost:8081/chat');
this.stompClient = Stomp.over(socket);
this.stompClient.connect({}, function(result) {
console.log('Connected: ' + result);
this.stompClient.subscribe('/topic/messages', function(message) {
console.log(message);
});
});
}
WebSocketConfig
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat").setAllowedOrigins("http://localhost:4200").withSockJS();
}
}
localhost : 8081 / chat / info? t = 1490866768565
{"entropy":-1720701276,"origins":["*:*"],"cookie_needed":true,"websocket":true}
MessageController
public class MessageController {
@MessageMapping("/chat")
@SendTo("/topic/messages")
public Message send(Message message) throws Exception {
return new Message(message.getFrom(), message.getText());
}
}
SecurityConfig (일시적으로 모두 허용)
public class SecurityConfig extends Auth0SecurityConfig {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll();
}
}
최신 정보
더 많은 테스트와 조사를 한 후에는 Chrome을 사용할 때만 문제가 발생하는 것 같습니다. 문제는 https://github.com/sockjs/sockjs-node/issues/177과 관련이있을 수 있습니다.
최신 정보
언급 된 chsdk와 같은 CORSFilter를 만들고 addFilterBefore () 메서드를 사용했습니다. https://stackoverflow.com/a/40300363/4836952.
@Bean
CORSFilter corsFilter() {
CORSFilter filter = new CORSFilter();
return filter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(corsFilter(), SessionManagementFilter.class).authorizeRequests().anyRequest().permitAll();
http.csrf().disable();
}
디버깅을 통해 필터가 호출되었지만 올바른 Access-Control-Allow-Origin이 설정된 경우에도 오류 메시지가 클라이언트 측에 계속 표시됩니다.
해결법
-
==============================
1.문제:
문제:
'Access-Control-Allow-Origin'을 올바르게 구성하지 않아 현재 구성이 서버에서 무시됩니다.
상태:
오류 스택 추적 :
와일드 카드 "*"에 'Access-Control-Allow-Origin'을 설정할 수 없다는 점 외에도 도메인 'http : // localhost : 4200'에도 액세스가 허용되지 않습니다.
귀하의 질문에 대답하려면 :
해결책:
아마 WebSocketConfig에 허용 된 출처를 설정할 필요는 없다고 생각합니다. WebSocketConfig는 Spring 설명서의 WebSocket Support에 명시된대로 웹 응용 프로그램에서 WebSocket 스타일의 메시징을 구성하기위한 것이기 때문에 CORSFilter 구성 클래스에서 구성해야합니다. 웹 응용 프로그램 액세스를위한 스프링 필터를 구성합니다.
이것은 CORSFilter.java 구성 클래스에 필요한 것입니다.
public class CORSFilter implements Filter { // This is to be replaced with a list of domains allowed to access the server //You can include more than one origin here private final List<String> allowedOrigins = Arrays.asList("http://localhost:4200"); public void destroy() { } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { // Lets make sure that we are working with HTTP (that is, against HttpServletRequest and HttpServletResponse objects) if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; // Access-Control-Allow-Origin String origin = request.getHeader("Origin"); response.setHeader("Access-Control-Allow-Origin", allowedOrigins.contains(origin) ? origin : ""); response.setHeader("Vary", "Origin"); // Access-Control-Max-Age response.setHeader("Access-Control-Max-Age", "3600"); // Access-Control-Allow-Credentials response.setHeader("Access-Control-Allow-Credentials", "true"); // Access-Control-Allow-Methods response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); // Access-Control-Allow-Headers response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, " + "X-CSRF-TOKEN"); } chain.doFilter(req, res); } public void init(FilterConfig filterConfig) { } }
당신은 다음의 사용을 볼 수 있습니다 :
private final List<String> allowedOrigins = Arrays.asList("http://localhost:4200");
서버에 액세스하도록 허용 된 도메인 목록을 설정합니다.
참고 문헌 :
스프링 프레임 워크의 CORS 지원과 RESTful 웹 서비스에 대한 교차 원점 요청 활성화에 대한 추가 정보가 필요합니다.
-
==============================
2.이것은 스프링 또는 각도 앱 코드와 아무 관련이 없습니다.
이것은 스프링 또는 각도 앱 코드와 아무 관련이 없습니다.
문제 소개 Access-Control-Allow-Origin은 웹 서버에 도메인 간 액세스 제어를 제공하는 CORS (Cross-Origin Resource Sharing) 메커니즘의 일부입니다. 앱 / 사이트를 CSRF (교차 사이트 요청 위조)로부터 보호하기위한 장소입니다.
CORS / CSRF
문제 이제 우리가 신중하게 오류를 읽으면
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:4200' is therefore not allowed access.
그것은 Access-Control-Allow-Origin 헤더가 와일드 카드가 될 수 없다고 말합니다.
다른 말로 이제 백 엔드는 웹에서 모든 사람이 내 사이트에서 코드를 실행할 수 있다고 말합니다.
달성하려는 목표 : 출처를 프런트 엔드 앱 (ng2)으로 제한하십시오.
해결책 이제는 Spring을 사용하고 있기 때문에 Apache Tomcat에서 백엔드 웹 서버로 사용한다고 가정합니다.
CORS는 web.conf (tomcat 폴더)에서 필터로 정의됩니다.
이 줄을 찾아라.
<init-param> <param-name>cors.allowed.origins</param-name> <param-value>*</param-value> </init-param>
*를 http : // localhost : 4200으로 변경하십시오.
Tomcat의 CORS 구성에 대한 자세한 내용은 다음을 참조하십시오.
EDIT (스프링 부트) 스프링 부트를 사용하기 때문에 프레임 구성에 cors 구성을 위임 할 수 있습니다.
스프링 부트로 CORS 설정을 더 잘 이해하려면 spring.io (chsdk 제안) 튜토리얼을 따르십시오.
-
==============================
3.내 대답은 너무 늦었지만, 누군가가 똑같은 문제에 직면 할 수 있다면 나는 이것을 게시 할 것이다. 나는 같은 공통 기원 문제에 직면 해왔다.
내 대답은 너무 늦었지만, 누군가가 똑같은 문제에 직면 할 수 있다면 나는 이것을 게시 할 것이다. 나는 같은 공통 기원 문제에 직면 해왔다.
기본적으로 서버 측 애플리케이션에 구현 된 스프링 보안을 사용하는 경우, 아마도 웹 소켓 핸드 셰이커를 차단하는 사람 일 것입니다
당신은 소켓 핸드 쉐이크를 허용하기 위해 웹 보안 엔드 포인트가 허용하도록 Spring 보안에 지시해야합니다 ... ~을 사용하여
.antMatchers("/socket/**").permitAll()
따라서 sockjs는 이제 Websocket 프로토콜로 전환하기 전에 핸드 셰이크에 대한 GET (HTTP) 요청을 보낼 수 있습니다.
이것은 스프링 보안 구성입니다.
package org.souhaib.caremy.security.module.config; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .exceptionHandling().authenticationEntryPoint(restAuthenticationEntryPoint).and() .authorizeRequests() .antMatchers(SecurityParams.PUBLIC_ROUTES).permitAll() .antMatchers("/socket/**").permitAll(); http.csrf().disable(); }}
이것은 WebSocket Broker 구성입니다.
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/socket") .setAllowedOrigins("http://localhost:4200") .withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.setApplicationDestinationPrefixes("/app") .enableSimpleBroker("/chat"); } }
-
==============================
4..setAllowedOrigins ( "*")를 webSocket config에 추가하기 만하면됩니다.
.setAllowedOrigins ( "*")를 webSocket config에 추가하기 만하면됩니다.
@Override public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { stompEndpointRegistry.addEndpoint("/yourEndpoint"); stompEndpointRegistry.addEndpoint("/yourEndpoint").setAllowedOrigins("*").withSockJS(); }
webSocket의 버전은 1.4.1입니다. 릴리스가 표시되지 않으면 버전을 업데이트해야합니다.
from https://stackoverflow.com/questions/43114750/header-in-the-response-must-not-be-the-wildcard-when-the-requests-credentia by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring으로부터 Hibernate Configuration 객체를 얻으려면 어떻게해야합니까? (0) | 2019.03.24 |
---|---|
[SPRING] 봄에서 목록의 페이지로 변환 (0) | 2019.03.24 |
[SPRING] Class 객체를 설정하기위한 Spring 구문? (0) | 2019.03.24 |
[SPRING] Spring @Value 이스케이프 콜론 (:) 기본값 (0) | 2019.03.24 |
[SPRING] 메인 클래스를 찾을 수 없습니다 : bootRepackage (0) | 2019.03.24 |