Last active
August 29, 2015 14:14
-
-
Save sdeleuze/a522ef9096b03737e553 to your computer and use it in GitHub Desktop.
Smart same origin check
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public abstract class AbstractSockJsService implements SockJsService { | |
// ... | |
private static final String XFRAME_OPTIONS_HEADER = "X-Frame-Options"; | |
// ... | |
/** | |
* Check the {@code Origin} header value and eventually call {@link #addCorsHeaders(ServerHttpRequest, ServerHttpResponse, HttpMethod...)}. | |
* If the request origin is not allowed, the request is rejected. | |
* @return false if the request is rejected, else true | |
* @since 4.1.2 | |
*/ | |
protected boolean checkAndAddCorsHeaders(ServerHttpRequest request, ServerHttpResponse response, HttpMethod... httpMethods) { | |
HttpHeaders requestHeaders = request.getHeaders(); | |
HttpHeaders responseHeaders = response.getHeaders(); | |
String origin = requestHeaders.getOrigin(); | |
String host = requestHeaders.getFirst(HttpHeaders.HOST); | |
if (origin == null) { | |
return true; | |
} | |
if (!isValidOrigin(origin, host)) { | |
logger.debug("Request rejected, Origin header value " + origin + " not allowed"); | |
response.setStatusCode(HttpStatus.FORBIDDEN); | |
return false; | |
} | |
boolean hasCorsResponseHeaders = false; | |
try { | |
// Perhaps a CORS Filter has already added this? | |
hasCorsResponseHeaders = !CollectionUtils.isEmpty(responseHeaders.get("Access-Control-Allow-Origin")); | |
} | |
catch (NullPointerException npe) { | |
// See SPR-11919 and https://issues.jboss.org/browse/WFLY-3474 | |
} | |
if (!this.suppressCors && !hasCorsResponseHeaders) { | |
addCorsHeaders(request, response, httpMethods); | |
} | |
return true; | |
} | |
private boolean isValidOrigin(String origin, String host) { | |
if (this.allowedOrigins.isEmpty()) { | |
UriComponents originComponents; | |
UriComponents hostComponents; | |
try { | |
originComponents = UriComponentsBuilder.fromHttpUrl(origin).build(); | |
} catch(IllegalArgumentException ex) { | |
logger.debug("Invalid Origin header " + origin); | |
return false; | |
} | |
try { | |
hostComponents = UriComponentsBuilder.fromHttpUrl("http://" + host).build(); | |
} catch(IllegalArgumentException ex) { | |
logger.debug("Invalid Host header " + host); | |
return false; | |
} | |
if (originComponents.getHost().equals(hostComponents.getHost()) | |
&& (originComponents.getPort() == hostComponents.getPort())) { | |
return true; | |
} | |
} else if (this.allowedOrigins.contains("*")) { | |
return true; | |
} else { | |
return this.allowedOrigins.contains(origin); | |
} | |
return false; | |
} | |
@Override | |
public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response, | |
String sockJsPath, WebSocketHandler wsHandler) throws SockJsException { | |
// ... | |
else if (sockJsPath.matches("/iframe[0-9-.a-z_]*.html")) { | |
// ... | |
if (this.allowedOrigins.isEmpty()) { | |
response.getHeaders().add(XFRAME_OPTIONS_HEADER, "SAMEORIGIN"); | |
} | |
// ... | |
} | |
// ... | |
} | |
// ... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment