Skip to content

Instantly share code, notes, and snippets.

@sdeleuze
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sdeleuze/a522ef9096b03737e553 to your computer and use it in GitHub Desktop.
Save sdeleuze/a522ef9096b03737e553 to your computer and use it in GitHub Desktop.
Smart same origin check
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