/********************************************************************************************************************* | |
* 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> | |
* <Set name="handler"> | |
* <New id="security" class="org.eclipse.smila.http.server.jetty.PortConstraintSecurityHandler"> | |
* <Set name="NoAuthenticationPort">8080</Set> | |
* <Set name="Strict">false</Set> | |
* <Set name="Authenticator"> | |
* <New class="org.eclipse.jetty.security.authentication.BasicAuthenticator" /> | |
* </Set> | |
* <Set name="ConstraintMappings"> | |
* <Array type="org.eclipse.jetty.security.ConstraintMapping"> | |
* <Item> | |
* <New class="org.eclipse.jetty.security.ConstraintMapping"> | |
* <Set name="PathSpec">/*</Set> | |
* <Set name="Constraint"> | |
* <New class="org.eclipse.jetty.util.security.Constraint"> | |
* <Set name="Authenticate">true</Set> | |
* <Set name="Roles"> | |
* <Array type="java.lang.String"> | |
* <Item>*</Item> | |
* </Array> | |
* </Set> | |
* </New> | |
* </Set> | |
* </New> | |
* </Item> | |
* </Array> | |
* </Set> | |
* <Set name="handler"> | |
* <New id="Contexts" class="org.eclipse.jetty.server.handler.HandlerCollection" /> | |
* </Set> | |
* </New> | |
* </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); | |
} | |
} |