When null origin is supported then credentials header must not be set.

Motivation:
Currently CORS can be configured to support a 'null' origin, which can
be set by a browser if a resources is loaded from the local file system.
When this is done 'Access-Control-Allow-Origin' will be set to "*" (any
origin). There is also a configuration option to allow credentials being
sent from the client (cookies, basic HTTP Authentication, client side
SSL). This is indicated by the response header
'Access-Control-Allow-Credentials' being set to true. When this is set
to true, the "*" origin is not valid as the value of
'Access-Control-Allow-Origin' and a browser will reject the request:
http://www.w3.org/TR/cors/#resource-requests

Modifications:
Updated CorsHandler's setAllowCredentials to check the origin and if it
is "*" then it will not add the 'Access-Control-Allow-Credentials'
header.

Result:
Is is possible to have a client send a 'null' origin, and at the same
time have configured the CORS to support that and to allow credentials
in that combination.

Conflicts:
	codec-http/src/main/java/io/netty/handler/codec/http/cors/CorsHandler.java
This commit is contained in:
Daniel Bevenius 2015-02-18 14:33:24 +01:00
parent 2aad79fcca
commit a9794342e1
2 changed files with 9 additions and 3 deletions

View File

@ -40,6 +40,7 @@ import static io.netty.util.ReferenceCountUtil.release;
public class CorsHandler extends ChannelDuplexHandler {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(CorsHandler.class);
private static final String ANY_ORIGIN = "*";
private final CorsConfig config;
private HttpRequest request;
@ -140,7 +141,7 @@ public class CorsHandler extends ChannelDuplexHandler {
}
private static void setAnyOrigin(final HttpResponse response) {
setOrigin(response, "*");
setOrigin(response, ANY_ORIGIN);
}
private static void setOrigin(final HttpResponse response, final String origin) {
@ -148,7 +149,8 @@ public class CorsHandler extends ChannelDuplexHandler {
}
private void setAllowCredentials(final HttpResponse response) {
if (config.isCredentialsAllowed()) {
if (config.isCredentialsAllowed()
&& !response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN).equals(ANY_ORIGIN)) {
response.headers().set(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
}
}

View File

@ -155,9 +155,13 @@ public class CorsHandlerTest {
@Test
public void preflightRequestWithNullOrigin() {
final String origin = "null";
final CorsConfig config = CorsConfig.withOrigin(origin).allowNullOrigin().build();
final CorsConfig config = CorsConfig.withOrigin(origin)
.allowNullOrigin()
.allowCredentials()
.build();
final HttpResponse response = preflightRequest(config, origin, "content-type, xheader1");
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is(equalTo("*")));
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_CREDENTIALS), is(nullValue()));
}
@Test