요청의 자격 증명 모드가 '포함'인 경우 응답의 헤더는 와일드카드 '*'이 되어서는 안 됩니다.
사용하고 있습니다.Auth0
합니다 Spring팅) 수 하는 내 인증에 됩니다.RestController
가 . 에서 수 Angular 2
localhost:4200
하여 Spring 서버(localhost:8081) 합니다를 :8081)에합니다.stompjs
그리고.sockjs
.
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.
이 문제를 조사한 결과 옵션 오리진 = * 및 자격 증명 = 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);
});
});
}
웹소켓구성
@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}
메시지컨트롤러
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();
}
}
갱신하다
몇 가지 테스트와 연구를 더 해본 결과 크롬에서만 문제가 발생하는 것 같습니다.문제는 다음과 관련이 있을 수 있습니다. 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이 설정되더라도 클라이언트 측에 오류 메시지가 계속 나타납니다.
문제:
를(를) 구성하고 있지 .'Access-Control-Allow-Origin'
정확하게 그리고 현재 구성은 단순히 서버에 의해 무시됩니다.
상황:
Error stack trace는 다음과 같이 말합니다.
의 입니다.
'Access-Control-Allow-Origin'
다가 .'*'
요청의 자격 증명 모드가 'include'인 경우.따라서 오리진 'http://localhost:4200'은(는) 접근이 허용되지 않습니다.
수 는 말입니다.'Access-Control-Allow-Origin'
"*"
, 'http://localhost:4200'
접근도 허용되지 않습니다.
질문에 대답하기
WebSocketConfig에서 허용된 오리진을 클라이언트 도메인으로 이미 설정했는데 어떻게 해결할 수 있습니까?
해결책:
에 될 것 .WebSocketConfig
웹 애플리케이션에서 WebSocket Support in Spring 문서에 명시된 대로 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");
서버에 액세스할 수 있는 도메인 목록을 설정합니다.
참조:
자세한 내용을 보려면 Spring Framework의 CORS 지원과 RESTful 웹 서비스에 대한 교차 오리진 요청 활성화를 확인해야 할 수도 있습니다.
이것은 당신의 스프링이나 각진 앱 코드와는 아무런 관련이 없습니다.
합니다.
Access-Control-Allow-Origin은 웹 서버에 도메인 간 액세스 제어를 제공하는 CORS(Cross-Origin Resource Sharing) 메커니즘의 일부입니다.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가 제안한 것과 같이) 이 자습서를 따르십시오.
제 대답은 너무 늦었지만 누군가가 같은 문제에 직면할 수 있다면 이 글을 올립니다. 저는 같은 origin 간 문제에 직면해 있었습니다.
기본적으로 서버측 애플리케이션에 구현된 Spring Security를 사용하는 경우 웹소켓 핸드셰이커를 차단하는 것은 아마도 그일 것입니다.
소켓 핸드셰이크를 허용하려면 웹소켓 엔드포인트를 허용하라고 Spring 보안부에 말해야 합니다.사용.
.antMatchers("/socket/**").permitAll()
따라서 sockjs는 이제 웹소켓 프로토콜로 전환하기 전에 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");
}
}
당신은 아래와 같이 당신의 코르를 구성하기만 하면 됩니다.
Othorize OPTION 방법을 수업시간에 제시하였습니다.
@Component
public class CORSFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String origin = request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", origin );
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token, Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-Dest");
response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(request, response);
}
}
이 코드에 주의하세요.브라우저에서 첫 번째 OPTION 요청을 리디렉션하기 때문입니다.
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(request, response);
}
이 구성 라인에서 자격 증명을 허용합니다.
response.setHeader("Access-Control-Allow-Credentials", "true");
그리고 이 라인에서 모든 오리진을 수락하면 브라우저 오리진을 해제하는 것이 권장되지는 않습니다.
String origin = request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", origin );
추가하기만 하면 됩니다..setAllowedOrigins("*")
webSocket config에서.
@Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry.addEndpoint("/yourEndpoint");
stompEndpointRegistry.addEndpoint("/yourEndpoint").setAllowedOrigins("*").withSockJS();
}
웹소켓의 버전은 1.4.1입니다.릴리스, 메서드가 표시되지 않았다면 버전을 업데이트해야 합니다.
언급URL : https://stackoverflow.com/questions/43114750/header-in-the-response-must-not-be-the-wildcard-when-the-requests-credentia
'programing' 카테고리의 다른 글
Objective-C Project에서 Swift Pod Framework 가져오기 및 사용 방법 (0) | 2023.10.14 |
---|---|
MariaDB 설치 시 도커 빌드 고착 (0) | 2023.10.14 |
Laravel 상위 행을 삭제하거나 업데이트할 수 없음: 외부 키 제약 조건이 실패함 (0) | 2023.10.14 |
오류 2013(HY000):'승인 패킷 읽기'에서 MySQL 서버에 대한 연결이 끊어졌습니다. 시스템 오류: 0 (0) | 2023.10.14 |
가능한 중복된 날짜의 총 길이를 찾기 위해 Oracle 쿼리를 작성하는 방법 (0) | 2023.10.14 |