KEYCLOAK-14232 Add Referrer-Policy: no-referrer to each response from Keycloak
(cherry picked from commit 0b49640231abc6e465542bd2608e1c908c079ced)
This commit is contained in:
parent
f037dabdc1
commit
f7e0af438d
11 changed files with 140 additions and 159 deletions
145
server-spi-private/src/main/java/org/keycloak/models/BrowserSecurityHeaders.java
Executable file → Normal file
145
server-spi-private/src/main/java/org/keycloak/models/BrowserSecurityHeaders.java
Executable file → Normal file
|
@ -21,125 +21,54 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class BrowserSecurityHeaders {
|
||||
public enum BrowserSecurityHeaders {
|
||||
|
||||
public static final String X_FRAME_OPTIONS = "X-Frame-Options";
|
||||
X_FRAME_OPTIONS("xFrameOptions", "X-Frame-Options", "SAMEORIGIN"),
|
||||
CONTENT_SECURITY_POLICY("contentSecurityPolicy", "Content-Security-Policy", ContentSecurityPolicyBuilder.create().build()),
|
||||
CONTENT_SECURITY_POLICY_REPORT_ONLY("contentSecurityPolicyReportOnly", "Content-Security-Policy-Report-Only", ""),
|
||||
X_CONTENT_TYPE_OPTIONS("xContentTypeOptions", "X-Content-Type-Options", "nosniff"),
|
||||
X_ROBOTS_TAG("xRobotsTag", "X-Robots-Tag", "none"),
|
||||
X_XSS_PROTECTION("xXSSProtection", "X-XSS-Protection", "1; mode=block"),
|
||||
STRICT_TRANSPORT_SECURITY("strictTransportSecurity", "Strict-Transport-Security", "max-age=31536000; includeSubDomains"),
|
||||
REFERRER_POLICY("referrerPolicy", "Referrer-Policy", "no-referrer"),
|
||||
;
|
||||
|
||||
public static final String X_FRAME_OPTIONS_DEFAULT = "SAMEORIGIN";
|
||||
private final String key;
|
||||
private final String headerName;
|
||||
private final String defaultValue;
|
||||
|
||||
public static final String X_FRAME_OPTIONS_KEY = "xFrameOptions";
|
||||
BrowserSecurityHeaders(String key, String headerName, String defaultValue) {
|
||||
this.key = key;
|
||||
this.headerName = headerName;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public static final String CONTENT_SECURITY_POLICY = "Content-Security-Policy";
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public static final String CONTENT_SECURITY_POLICY_DEFAULT = ContentSecurityPolicyBuilder.create().build();
|
||||
public String getHeaderName() {
|
||||
return headerName;
|
||||
}
|
||||
|
||||
public static final String CONTENT_SECURITY_POLICY_KEY = "contentSecurityPolicy";
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static final String CONTENT_SECURITY_POLICY_REPORT_ONLY = "Content-Security-Policy-Report-Only";
|
||||
|
||||
public static final String CONTENT_SECURITY_POLICY_REPORT_ONLY_DEFAULT = "";
|
||||
|
||||
public static final String CONTENT_SECURITY_POLICY_REPORT_ONLY_KEY = "contentSecurityPolicyReportOnly";
|
||||
|
||||
public static final String X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
|
||||
|
||||
public static final String X_CONTENT_TYPE_OPTIONS_DEFAULT = "nosniff";
|
||||
|
||||
public static final String X_CONTENT_TYPE_OPTIONS_KEY = "xContentTypeOptions";
|
||||
|
||||
public static final String X_ROBOTS_TAG = "X-Robots-Tag";
|
||||
|
||||
public static final String X_ROBOTS_TAG_KEY = "xRobotsTag";
|
||||
|
||||
public static final String X_ROBOTS_TAG_DEFAULT = "none";
|
||||
|
||||
public static final String X_XSS_PROTECTION = "X-XSS-Protection";
|
||||
|
||||
public static final String X_XSS_PROTECTION_DEFAULT = "1; mode=block";
|
||||
|
||||
public static final String X_XSS_PROTECTION_KEY = "xXSSProtection";
|
||||
|
||||
public static final String STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security";
|
||||
|
||||
public static final String STRICT_TRANSPORT_SECURITY_DEFAULT = "max-age=31536000; includeSubDomains";
|
||||
|
||||
public static final String STRICT_TRANSPORT_SECURITY_KEY = "strictTransportSecurity";
|
||||
|
||||
public static final Map<String, String> headerAttributeMap;
|
||||
public static final Map<String, String> defaultHeaders;
|
||||
@Deprecated // should be removed eventually
|
||||
public static final Map<String, String> realmDefaultHeaders;
|
||||
|
||||
static {
|
||||
Map<String, String> headerMap = new HashMap<>();
|
||||
headerMap.put(X_FRAME_OPTIONS_KEY, X_FRAME_OPTIONS);
|
||||
headerMap.put(CONTENT_SECURITY_POLICY_KEY, CONTENT_SECURITY_POLICY);
|
||||
headerMap.put(CONTENT_SECURITY_POLICY_REPORT_ONLY_KEY, CONTENT_SECURITY_POLICY_REPORT_ONLY);
|
||||
headerMap.put(X_CONTENT_TYPE_OPTIONS_KEY, X_CONTENT_TYPE_OPTIONS);
|
||||
headerMap.put(X_ROBOTS_TAG_KEY, X_ROBOTS_TAG);
|
||||
headerMap.put(X_XSS_PROTECTION_KEY, X_XSS_PROTECTION);
|
||||
headerMap.put(STRICT_TRANSPORT_SECURITY_KEY, STRICT_TRANSPORT_SECURITY);
|
||||
|
||||
Map<String, String> dh = new HashMap<>();
|
||||
dh.put(X_FRAME_OPTIONS_KEY, X_FRAME_OPTIONS_DEFAULT);
|
||||
dh.put(CONTENT_SECURITY_POLICY_KEY, CONTENT_SECURITY_POLICY_DEFAULT);
|
||||
dh.put(CONTENT_SECURITY_POLICY_REPORT_ONLY_KEY, CONTENT_SECURITY_POLICY_REPORT_ONLY_DEFAULT);
|
||||
dh.put(X_CONTENT_TYPE_OPTIONS_KEY, X_CONTENT_TYPE_OPTIONS_DEFAULT);
|
||||
dh.put(X_ROBOTS_TAG_KEY, X_ROBOTS_TAG_DEFAULT);
|
||||
dh.put(X_XSS_PROTECTION_KEY, X_XSS_PROTECTION_DEFAULT);
|
||||
dh.put(STRICT_TRANSPORT_SECURITY_KEY, STRICT_TRANSPORT_SECURITY_DEFAULT);
|
||||
dh.put(X_FRAME_OPTIONS.getKey(), X_FRAME_OPTIONS.getDefaultValue());
|
||||
dh.put(CONTENT_SECURITY_POLICY.getKey(), CONTENT_SECURITY_POLICY.getDefaultValue());
|
||||
dh.put(CONTENT_SECURITY_POLICY_REPORT_ONLY.getKey(), CONTENT_SECURITY_POLICY_REPORT_ONLY.getDefaultValue());
|
||||
dh.put(X_CONTENT_TYPE_OPTIONS.getKey(), X_CONTENT_TYPE_OPTIONS.getDefaultValue());
|
||||
dh.put(X_ROBOTS_TAG.getKey(), X_ROBOTS_TAG.getDefaultValue());
|
||||
dh.put(X_XSS_PROTECTION.getKey(), X_XSS_PROTECTION.getDefaultValue());
|
||||
dh.put(STRICT_TRANSPORT_SECURITY.getKey(), STRICT_TRANSPORT_SECURITY.getDefaultValue());
|
||||
|
||||
defaultHeaders = Collections.unmodifiableMap(dh);
|
||||
headerAttributeMap = Collections.unmodifiableMap(headerMap);
|
||||
realmDefaultHeaders = Collections.unmodifiableMap(dh);
|
||||
}
|
||||
|
||||
public static class ContentSecurityPolicyBuilder {
|
||||
|
||||
private String frameSrc = "'self'";
|
||||
private String frameAncestors = "'self'";
|
||||
private String objectSrc = "'none'";
|
||||
|
||||
private boolean first;
|
||||
private StringBuilder sb;
|
||||
|
||||
public static ContentSecurityPolicyBuilder create() {
|
||||
return new ContentSecurityPolicyBuilder();
|
||||
}
|
||||
|
||||
public ContentSecurityPolicyBuilder frameSrc(String frameSrc) {
|
||||
this.frameSrc = frameSrc;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentSecurityPolicyBuilder frameAncestors(String frameancestors) {
|
||||
this.frameAncestors = frameancestors;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String build() {
|
||||
sb = new StringBuilder();
|
||||
first = true;
|
||||
|
||||
build("frame-src", frameSrc);
|
||||
build("frame-ancestors", frameAncestors);
|
||||
build("object-src", objectSrc);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void build(String k, String v) {
|
||||
if (v != null) {
|
||||
if (!first) {
|
||||
sb.append(" ");
|
||||
}
|
||||
first = false;
|
||||
|
||||
sb.append(k).append(" ").append(v).append(";");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package org.keycloak.models;
|
||||
|
||||
public class ContentSecurityPolicyBuilder {
|
||||
|
||||
private String frameSrc = "'self'";
|
||||
private String frameAncestors = "'self'";
|
||||
private String objectSrc = "'none'";
|
||||
|
||||
private boolean first;
|
||||
private StringBuilder sb;
|
||||
|
||||
public static ContentSecurityPolicyBuilder create() {
|
||||
return new ContentSecurityPolicyBuilder();
|
||||
}
|
||||
|
||||
public ContentSecurityPolicyBuilder frameSrc(String frameSrc) {
|
||||
this.frameSrc = frameSrc;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentSecurityPolicyBuilder frameAncestors(String frameancestors) {
|
||||
this.frameAncestors = frameancestors;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String build() {
|
||||
sb = new StringBuilder();
|
||||
first = true;
|
||||
|
||||
build("frame-src", frameSrc);
|
||||
build("frame-ancestors", frameAncestors);
|
||||
build("object-src", objectSrc);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void build(String k, String v) {
|
||||
if (v != null) {
|
||||
if (!first) {
|
||||
sb.append(" ");
|
||||
}
|
||||
first = false;
|
||||
|
||||
sb.append(k).append(" ").append(v).append(";");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -387,7 +387,7 @@ public class RepresentationToModel {
|
|||
if (rep.getBrowserSecurityHeaders() != null) {
|
||||
newRealm.setBrowserSecurityHeaders(rep.getBrowserSecurityHeaders());
|
||||
} else {
|
||||
newRealm.setBrowserSecurityHeaders(BrowserSecurityHeaders.defaultHeaders);
|
||||
newRealm.setBrowserSecurityHeaders(BrowserSecurityHeaders.realmDefaultHeaders);
|
||||
}
|
||||
|
||||
if (rep.getComponents() != null) {
|
||||
|
|
|
@ -8,10 +8,10 @@ public class BrowserSecurityHeadersTest {
|
|||
|
||||
@Test
|
||||
public void contentSecurityPolicyBuilderTest() {
|
||||
assertEquals("frame-src 'self'; frame-ancestors 'self'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().build());
|
||||
assertEquals("frame-ancestors 'self'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().frameSrc(null).build());
|
||||
assertEquals("frame-src 'self'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().frameAncestors(null).build());
|
||||
assertEquals("frame-src 'custom-frame-src'; frame-ancestors 'custom-frame-ancestors'; object-src 'none';", BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create().frameSrc("'custom-frame-src'").frameAncestors("'custom-frame-ancestors'").build());
|
||||
assertEquals("frame-src 'self'; frame-ancestors 'self'; object-src 'none';", ContentSecurityPolicyBuilder.create().build());
|
||||
assertEquals("frame-ancestors 'self'; object-src 'none';", ContentSecurityPolicyBuilder.create().frameSrc(null).build());
|
||||
assertEquals("frame-src 'self'; object-src 'none';", ContentSecurityPolicyBuilder.create().frameAncestors(null).build());
|
||||
assertEquals("frame-src 'custom-frame-src'; frame-ancestors 'custom-frame-ancestors'; object-src 'none';", ContentSecurityPolicyBuilder.create().frameSrc("'custom-frame-src'").frameAncestors("'custom-frame-ancestors'").build());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.keycloak.headers;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.models.BrowserSecurityHeaders;
|
||||
import org.keycloak.models.ContentSecurityPolicyBuilder;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
||||
|
@ -26,8 +27,11 @@ import javax.ws.rs.container.ContainerRequestContext;
|
|||
import javax.ws.rs.container.ContainerResponseContext;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.keycloak.models.BrowserSecurityHeaders.CONTENT_SECURITY_POLICY;
|
||||
|
||||
public class DefaultSecurityHeadersProvider implements SecurityHeadersProvider {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(DefaultSecurityHeadersProvider.class);
|
||||
|
@ -44,7 +48,7 @@ public class DefaultSecurityHeadersProvider implements SecurityHeadersProvider {
|
|||
if (realm != null) {
|
||||
headerValues = realm.getBrowserSecurityHeaders();
|
||||
} else {
|
||||
headerValues = BrowserSecurityHeaders.defaultHeaders;
|
||||
headerValues = Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,27 +85,31 @@ public class DefaultSecurityHeadersProvider implements SecurityHeadersProvider {
|
|||
}
|
||||
|
||||
private void addGenericHeaders(MultivaluedMap<String, Object> headers) {
|
||||
addHeader(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY_KEY, headers);
|
||||
addHeader(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS_KEY, headers);
|
||||
addHeader(BrowserSecurityHeaders.X_XSS_PROTECTION_KEY, headers);
|
||||
addHeader(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY, headers);
|
||||
addHeader(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS, headers);
|
||||
addHeader(BrowserSecurityHeaders.X_XSS_PROTECTION, headers);
|
||||
addHeader(BrowserSecurityHeaders.REFERRER_POLICY, headers);
|
||||
}
|
||||
|
||||
private void addRestHeaders(MultivaluedMap<String, Object> headers) {
|
||||
addHeader(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY_KEY, headers);
|
||||
addHeader(BrowserSecurityHeaders.X_FRAME_OPTIONS_KEY, headers);
|
||||
addHeader(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS_KEY, headers);
|
||||
addHeader(BrowserSecurityHeaders.X_XSS_PROTECTION_KEY, headers);
|
||||
addHeader(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY, headers);
|
||||
addHeader(BrowserSecurityHeaders.X_FRAME_OPTIONS, headers);
|
||||
addHeader(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS, headers);
|
||||
addHeader(BrowserSecurityHeaders.X_XSS_PROTECTION, headers);
|
||||
addHeader(BrowserSecurityHeaders.REFERRER_POLICY, headers);
|
||||
}
|
||||
|
||||
private void addHtmlHeaders(MultivaluedMap<String, Object> headers) {
|
||||
BrowserSecurityHeaders.headerAttributeMap.keySet().forEach(k -> addHeader(k, headers));
|
||||
for (BrowserSecurityHeaders header : BrowserSecurityHeaders.values()) {
|
||||
addHeader(header, headers);
|
||||
}
|
||||
|
||||
// TODO This will be refactored as part of introducing a more strict CSP header
|
||||
if (options != null) {
|
||||
BrowserSecurityHeaders.ContentSecurityPolicyBuilder csp = BrowserSecurityHeaders.ContentSecurityPolicyBuilder.create();
|
||||
ContentSecurityPolicyBuilder csp = ContentSecurityPolicyBuilder.create();
|
||||
|
||||
if (options.isAllowAnyFrameAncestor()) {
|
||||
headers.remove(BrowserSecurityHeaders.X_FRAME_OPTIONS);
|
||||
headers.remove(BrowserSecurityHeaders.X_FRAME_OPTIONS.getHeaderName());
|
||||
|
||||
csp.frameAncestors(null);
|
||||
}
|
||||
|
@ -111,17 +119,16 @@ public class DefaultSecurityHeadersProvider implements SecurityHeadersProvider {
|
|||
csp.frameSrc(allowedFrameSrc);
|
||||
}
|
||||
|
||||
if (BrowserSecurityHeaders.CONTENT_SECURITY_POLICY_DEFAULT.equals(headers.getFirst(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY))) {
|
||||
headers.putSingle(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY, csp.build());
|
||||
if (CONTENT_SECURITY_POLICY.getDefaultValue().equals(headers.getFirst(CONTENT_SECURITY_POLICY.getHeaderName()))) {
|
||||
headers.putSingle(CONTENT_SECURITY_POLICY.getHeaderName(), csp.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addHeader(String key, MultivaluedMap<String, Object> headers) {
|
||||
String header = BrowserSecurityHeaders.headerAttributeMap.get(key);
|
||||
String value = headerValues.get(key);
|
||||
private void addHeader(BrowserSecurityHeaders header, MultivaluedMap<String, Object> headers) {
|
||||
String value = headerValues.getOrDefault(header.getKey(), header.getDefaultValue());
|
||||
if (value != null && !value.isEmpty()) {
|
||||
headers.putSingle(header, value);
|
||||
headers.putSingle(header.getHeaderName(), value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ public class RealmManager {
|
|||
|
||||
|
||||
protected void setupRealmDefaults(RealmModel realm) {
|
||||
realm.setBrowserSecurityHeaders(BrowserSecurityHeaders.defaultHeaders);
|
||||
realm.setBrowserSecurityHeaders(BrowserSecurityHeaders.realmDefaultHeaders);
|
||||
|
||||
// brute force
|
||||
realm.setBruteForceProtected(false); // default settings off for now todo set it on
|
||||
|
|
|
@ -1,22 +1,20 @@
|
|||
package org.keycloak.testsuite.admin;
|
||||
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpOptions;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.models.BrowserSecurityHeaders;
|
||||
import org.keycloak.services.resources.Cors;
|
||||
import org.keycloak.testsuite.util.UserBuilder;
|
||||
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class AdminHeadersTest extends AbstractAdminTest {
|
||||
|
||||
|
@ -42,14 +40,19 @@ public class AdminHeadersTest extends AbstractAdminTest {
|
|||
Response response = realm.users().create(UserBuilder.create().username("headers-user").build());
|
||||
MultivaluedMap<String, Object> h = response.getHeaders();
|
||||
|
||||
assertEquals(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY_DEFAULT, h.getFirst(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY));
|
||||
assertEquals(BrowserSecurityHeaders.X_FRAME_OPTIONS_DEFAULT, h.getFirst(BrowserSecurityHeaders.X_FRAME_OPTIONS));
|
||||
assertEquals(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS_DEFAULT, h.getFirst(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS));
|
||||
assertEquals(BrowserSecurityHeaders.X_XSS_PROTECTION_DEFAULT, h.getFirst(BrowserSecurityHeaders.X_XSS_PROTECTION));
|
||||
assertDefaultValue(BrowserSecurityHeaders.STRICT_TRANSPORT_SECURITY, h);
|
||||
assertDefaultValue(BrowserSecurityHeaders.X_FRAME_OPTIONS, h);
|
||||
assertDefaultValue(BrowserSecurityHeaders.X_CONTENT_TYPE_OPTIONS, h);
|
||||
assertDefaultValue(BrowserSecurityHeaders.X_XSS_PROTECTION, h);
|
||||
assertDefaultValue(BrowserSecurityHeaders.REFERRER_POLICY, h);
|
||||
|
||||
response.close();
|
||||
}
|
||||
|
||||
private void assertDefaultValue(BrowserSecurityHeaders header, MultivaluedMap<String, Object> h) {
|
||||
assertThat(h.getFirst(header.getHeaderName()), is(equalTo(header.getDefaultValue())));
|
||||
}
|
||||
|
||||
private String getAdminUrl(String resource) {
|
||||
return suiteContext.getAuthServerInfo().getContextRoot().toString() + "/auth/admin/" + resource;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package org.keycloak.testsuite.error;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
|
@ -14,7 +12,6 @@ import org.keycloak.admin.client.resource.RealmResource;
|
|||
import org.keycloak.broker.provider.util.SimpleHttp;
|
||||
import org.keycloak.common.util.StreamUtil;
|
||||
import org.keycloak.models.BrowserSecurityHeaders;
|
||||
import org.keycloak.representations.idm.ErrorRepresentation;
|
||||
import org.keycloak.representations.idm.OAuth2ErrorRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||
|
@ -31,7 +28,6 @@ import java.net.URI;
|
|||
import java.nio.charset.Charset;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
@ -126,14 +122,13 @@ public class UncaughtErrorPageTest extends AbstractKeycloakTest {
|
|||
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
|
||||
SimpleHttp.Response response = SimpleHttp.doGet(uri.toString(), client).header("Accept", MediaType.TEXT_HTML_UTF_8).asResponse();
|
||||
|
||||
for (Map.Entry<String, String> e : BrowserSecurityHeaders.headerAttributeMap.entrySet()) {
|
||||
String header = e.getValue();
|
||||
String expectedValue = BrowserSecurityHeaders.defaultHeaders.get(e.getKey());
|
||||
for (BrowserSecurityHeaders header : BrowserSecurityHeaders.values()) {
|
||||
String expectedValue = header.getDefaultValue();
|
||||
|
||||
if (expectedValue == null || expectedValue.isEmpty()) {
|
||||
assertNull(response.getFirstHeader(header));
|
||||
assertNull(response.getFirstHeader(header.getHeaderName()));
|
||||
} else {
|
||||
assertEquals(expectedValue, response.getFirstHeader(header));
|
||||
assertEquals(expectedValue, response.getFirstHeader(header.getHeaderName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,6 @@ import javax.ws.rs.core.UriBuilder;
|
|||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
|
||||
|
@ -164,14 +163,14 @@ public class LoginTest extends AbstractTestRealmKeycloakTest {
|
|||
Client client = ClientBuilder.newClient();
|
||||
Response response = client.target(oauth.getLoginFormUrl()).request().get();
|
||||
Assert.assertThat(response.getStatus(), is(equalTo(200)));
|
||||
for (Map.Entry<String, String> entry : BrowserSecurityHeaders.defaultHeaders.entrySet()) {
|
||||
String headerName = BrowserSecurityHeaders.headerAttributeMap.get(entry.getKey());
|
||||
String headerValue = response.getHeaderString(headerName);
|
||||
if (entry.getValue().isEmpty()) {
|
||||
for (BrowserSecurityHeaders header : BrowserSecurityHeaders.values()) {
|
||||
String headerValue = response.getHeaderString(header.getHeaderName());
|
||||
String expectedValue = header.getDefaultValue();
|
||||
if (expectedValue.isEmpty()) {
|
||||
Assert.assertNull(headerValue);
|
||||
} else {
|
||||
Assert.assertNotNull(headerValue);
|
||||
Assert.assertThat(headerValue, is(equalTo(entry.getValue())));
|
||||
Assert.assertThat(headerValue, is(equalTo(expectedValue)));
|
||||
}
|
||||
}
|
||||
response.close();
|
||||
|
|
|
@ -130,9 +130,9 @@ public class LoginStatusIframeEndpointTest extends AbstractKeycloakTest {
|
|||
assertTrue(s.contains("function getCookie()"));
|
||||
|
||||
assertEquals("CP=\"This is not a P3P policy!\"", response.getFirstHeader("P3P").getValue());
|
||||
assertNull(response.getFirstHeader(BrowserSecurityHeaders.X_FRAME_OPTIONS));
|
||||
assertEquals("frame-src 'self'; object-src 'none';", response.getFirstHeader(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY).getValue());
|
||||
assertEquals("none", response.getFirstHeader(BrowserSecurityHeaders.X_ROBOTS_TAG).getValue());
|
||||
assertNull(response.getFirstHeader(BrowserSecurityHeaders.X_FRAME_OPTIONS.getHeaderName()));
|
||||
assertEquals("frame-src 'self'; object-src 'none';", response.getFirstHeader(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY.getHeaderName()).getValue());
|
||||
assertEquals("none", response.getFirstHeader(BrowserSecurityHeaders.X_ROBOTS_TAG.getHeaderName()).getValue());
|
||||
|
||||
response.close();
|
||||
|
||||
|
|
|
@ -255,7 +255,7 @@ public class DefaultHostnameTest extends AbstractHostnameTest {
|
|||
assertTrue(indexPage.contains("consoleBaseUrl = '" + new URI(expectedAdminUrl).getPath() +"/admin/" + realm + "/console/'"));
|
||||
assertTrue(indexPage.contains("resourceUrl = '" + new URI(expectedAdminUrl).getPath() +"/resources/"));
|
||||
|
||||
String cspHeader = response.getFirstHeader(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY);
|
||||
String cspHeader = response.getFirstHeader(BrowserSecurityHeaders.CONTENT_SECURITY_POLICY.getHeaderName());
|
||||
|
||||
if (expectedFrontendUrl.equalsIgnoreCase(expectedAdminUrl)) {
|
||||
assertEquals("frame-src 'self'; frame-ancestors 'self'; object-src 'none';", cspHeader);
|
||||
|
|
Loading…
Reference in a new issue