blob: c6c98d0f2cec816e39cb0fd94ed39e4bba06d679 [file] [log] [blame]
/*********************************************************************************************************************
* Copyright (c) 2008, 2015 Empolis Information Management GmbH and brox IT Solutions GmbH. All rights reserved.
* This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
**********************************************************************************************************************/
package org.eclipse.smila.http.server.jetty;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.server.Request;
import org.eclipse.smila.http.server.util.CorsUtils;
/**
* Special version of Jetty's {@link ConstraintSecurityHandler} that allows unauthenticated communication on a
* configurable port. The use case for this is to configure SMILA with two HTTP ports: one allows unauthenticated access
* and is used for internal communication by other services in the SMILA cluster, but is not accessible by external
* client (e.g. blocked by a firewall). External clients can connect only to the second port which requires
* authentication (and maybe the HTTPS protocol).
*
* <p>
*
* Example for usage in jetty.xml: Talking to port 8080 does not require authentication, on all other ports
*
* <pre>
* &lt;Set name="handler">
* &lt;New id="security" class="org.eclipse.smila.http.server.jetty.PortConstraintSecurityHandler">
* &lt;Set name="NoAuthenticationPort">8080&lt;/Set>
* &lt;Set name="Strict">false&lt;/Set>
* &lt;Set name="Authenticator">
* &lt;New class="org.eclipse.jetty.security.authentication.BasicAuthenticator" />
* &lt;/Set>
* &lt;Set name="ConstraintMappings">
* &lt;Array type="org.eclipse.jetty.security.ConstraintMapping">
* &lt;Item>
* &lt;New class="org.eclipse.jetty.security.ConstraintMapping">
* &lt;Set name="PathSpec">/*&lt;/Set>
* &lt;Set name="Constraint">
* &lt;New class="org.eclipse.jetty.util.security.Constraint">
* &lt;Set name="Authenticate">true&lt;/Set>
* &lt;Set name="Roles">
* &lt;Array type="java.lang.String">
* &lt;Item>*&lt;/Item>
* &lt;/Array>
* &lt;/Set>
* &lt;/New>
* &lt;/Set>
* &lt;/New>
* &lt;/Item>
* &lt;/Array>
* &lt;/Set>
* &lt;Set name="handler">
* &lt;New id="Contexts" class="org.eclipse.jetty.server.handler.HandlerCollection" />
* &lt;/Set>
* &lt;/New>
* &lt;/Set>
* </pre>
*/
public class PortConstraintSecurityHandler extends ConstraintSecurityHandler {
private int _noAuthenticationPort;
/**
* Sets port that allows unauthenticated access. If never set or set to a value less or equal to 0, this class behaves
* exactly like {@link ConstraintSecurityHandler} and all ports require authentication.
*/
public void setNoAuthenticationPort(final int noAuthenticationPort) {
_noAuthenticationPort = noAuthenticationPort;
}
/**
* @return port for unauthenticated access.
*/
public int getNoAuthenticationPort() {
return _noAuthenticationPort;
}
@Override
protected boolean checkSecurity(final Request request) {
if (_noAuthenticationPort > 0 && request.getServerPort() == _noAuthenticationPort) {
return false;
}
// needed for preflight CORS requests: OPTIONS requests should not require authentication
if ("OPTIONS".equals(request.getMethod())) {
return false;
}
return super.checkSecurity(request);
}
@Override
public void handle(final String pathInContext, final Request baseRequest, final HttpServletRequest request,
final HttpServletResponse response) throws IOException, ServletException {
CorsUtils.setCorsResponseHandlers(request, response);
super.handle(pathInContext, baseRequest, request, response);
}
}