Initial check in accordance with Parallel IP

This commit is contained in:
Kai Zimmermann
2016-01-21 13:18:55 +01:00
parent c5e4f1139f
commit 7497ab61ed
763 changed files with 114508 additions and 0 deletions

View File

@@ -0,0 +1,180 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* 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.hawkbit.security;
import java.io.IOException;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.util.AntPathMatcher;
import com.google.common.collect.Iterators;
import com.google.common.collect.UnmodifiableIterator;
/**
* An abstraction for all controller based security to parse the e.g. the tenant
* name from the URL and the controller ID from the URL to do security checks
* based on these information.
*
*
*
*
*/
public abstract class AbstractHttpControllerAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractHttpControllerAuthenticationFilter.class);
private static final String TENANT_PLACE_HOLDER = "tenant";
private static final String CONTROLLER_ID_PLACE_HOLDER = "controllerId";
/**
* requestURIPathPattern the request URI path pattern in ANT style
* containing the placeholder key for retrieving the principal from the URI
* request. e.g."/{tenant}/controller/v1/{controllerId}
*/
private static final String CONTROLLER_REQUEST_ANT_PATTERN = "/{" + TENANT_PLACE_HOLDER + "}/controller/v1" + "/{"
+ CONTROLLER_ID_PLACE_HOLDER + "}/**";
private static final String CONTROLLER_DL_REQUEST_ANT_PATTERN = "/{" + TENANT_PLACE_HOLDER
+ "}/controller/artifacts/v1/**";
protected SystemManagement systemManagement;
protected TenantAware tenantAware;
private final AntPathMatcher pathExtractor;
private PreAuthenficationFilter abstractControllerAuthenticationFilter;
/**
* Constructor for sub-classes.
*
* @param systemManagement
* the system management service
* @param tenantAware
* the tenant aware service
*/
public AbstractHttpControllerAuthenticationFilter(final SystemManagement systemManagement,
final TenantAware tenantAware) {
this.systemManagement = systemManagement;
this.tenantAware = tenantAware;
pathExtractor = new AntPathMatcher();
}
/*
* (non-Javadoc)
*
* @see org.springframework.security.web.authentication.preauth.
* AbstractPreAuthenticatedProcessingFilter
* #doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
* javax.servlet.FilterChain)
*/
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
chain.doFilter(request, response);
return;
}
final TenantSecruityToken secruityToken = createTenantSecruityTokenVariables((HttpServletRequest) request);
if (secruityToken == null) {
chain.doFilter(request, response);
return;
}
abstractControllerAuthenticationFilter = createControllerAuthenticationFilter();
if (abstractControllerAuthenticationFilter.isEnable(secruityToken)
&& SecurityContextHolder.getContext().getAuthentication() == null) {
super.doFilter(request, response, chain);
} else {
chain.doFilter(request, response);
}
}
protected abstract PreAuthenficationFilter createControllerAuthenticationFilter();
/**
* Extracts tenant and controllerId from the request URI as path variables.
*
* @param request
* the Http request to extract the path variables.
* @return the extracted {@link PathVariables} or {@code null} if the
* request does not match the pattern and no variables could be
* extracted
*/
protected TenantSecruityToken createTenantSecruityTokenVariables(final HttpServletRequest request) {
final String requestURI = request.getRequestURI();
if (pathExtractor.match(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI)) {
LOGGER.debug("retrieving principal from URI request {}", requestURI);
final Map<String, String> extractUriTemplateVariables = pathExtractor
.extractUriTemplateVariables(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI);
final String controllerId = extractUriTemplateVariables.get(CONTROLLER_ID_PLACE_HOLDER);
final String tenant = extractUriTemplateVariables.get(TENANT_PLACE_HOLDER);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parsed tenant {} and controllerId {} from path request {}", tenant, controllerId,
requestURI);
}
return createTenantSecruityTokenVariables(request, tenant, controllerId);
} else if (pathExtractor.match(request.getContextPath() + CONTROLLER_DL_REQUEST_ANT_PATTERN, requestURI)) {
LOGGER.debug("retrieving path variables from URI request {}", requestURI);
final Map<String, String> extractUriTemplateVariables = pathExtractor.extractUriTemplateVariables(
request.getContextPath() + CONTROLLER_DL_REQUEST_ANT_PATTERN, requestURI);
final String tenant = extractUriTemplateVariables.get(TENANT_PLACE_HOLDER);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parsed tenant {} from path request {}", tenant, requestURI);
}
return createTenantSecruityTokenVariables(request, tenant, "anonymous");
} else {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("request {} does not match the path pattern {}, request gets ignored", requestURI,
CONTROLLER_REQUEST_ANT_PATTERN);
}
return null;
}
}
private TenantSecruityToken createTenantSecruityTokenVariables(final HttpServletRequest request,
final String tenant, final String controllerId) {
final TenantSecruityToken secruityToken = new TenantSecruityToken(tenant, controllerId, "");
final UnmodifiableIterator<String> forEnumeration = Iterators.forEnumeration(request.getHeaderNames());
forEnumeration.forEachRemaining(header -> secruityToken.getHeaders().put(header, request.getHeader(header)));
return secruityToken;
}
@Override
protected Object getPreAuthenticatedPrincipal(final HttpServletRequest request) {
final TenantSecruityToken secruityToken = createTenantSecruityTokenVariables(request);
if (secruityToken == null) {
return null;
}
return abstractControllerAuthenticationFilter.getPreAuthenticatedPrincipal(secruityToken);
}
@Override
protected Object getPreAuthenticatedCredentials(final HttpServletRequest request) {
final TenantSecruityToken secruityToken = createTenantSecruityTokenVariables(request);
if (secruityToken == null) {
return null;
}
return abstractControllerAuthenticationFilter.getPreAuthenticatedCredentials(secruityToken);
}
}

View File

@@ -0,0 +1,76 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* 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.hawkbit.security;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.util.AntPathMatcher;
/**
* An {@link AuthenticationDetailsSource} implementation which retrieves the
* tenant from a request pattern {@link #TENANT_AWARE_CONTROLLER_PATTERN} and
* stores the retrieved tenant in the {@link TenantAwareAuthenticationDetails}.
*
*
*/
public class ControllerTenantAwareAuthenticationDetailsSource
implements AuthenticationDetailsSource<HttpServletRequest, TenantAwareAuthenticationDetails> {
/**
*
*/
private static final String TENANT_AWARE_CONTROLLER_PATTERN = "/{tenant}/controller/**";
private static final Logger LOGGER = LoggerFactory
.getLogger(ControllerTenantAwareAuthenticationDetailsSource.class);
private static final String TENANT_PLACE_HOLDER = "tenant";
private final AntPathMatcher pathExtractor;
/**
*
*/
public ControllerTenantAwareAuthenticationDetailsSource() {
pathExtractor = new AntPathMatcher();
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.security.authentication.AuthenticationDetailsSource#
* buildDetails(java. lang.Object)
*/
@Override
public TenantAwareAuthenticationDetails buildDetails(final HttpServletRequest request) {
return new TenantAwareWebAuthenticationDetails(getTenantFromRequestUri(request), request.getRemoteAddr(), true);
}
private String getTenantFromRequestUri(final HttpServletRequest request) {
final String requestURI = request.getRequestURI();
LOGGER.debug("retrieving tenant from URI request {}", requestURI);
final String requestPathPattern = request.getContextPath() + TENANT_AWARE_CONTROLLER_PATTERN;
if (!pathExtractor.match(requestPathPattern, requestURI)) {
LOGGER.info("Controller request not matching tenant aware request pattern requestpath: {}, pattern {}",
requestURI, TENANT_AWARE_CONTROLLER_PATTERN);
return null;
}
final Map<String, String> extractUriTemplateVariables = pathExtractor
.extractUriTemplateVariables(requestPathPattern, requestURI);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parsed path variables {} using tenant {}", extractUriTemplateVariables,
extractUriTemplateVariables.get(TENANT_PLACE_HOLDER));
}
return extractUriTemplateVariables.get(TENANT_PLACE_HOLDER);
}
}

View File

@@ -0,0 +1,59 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* 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.hawkbit.security;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.tenancy.TenantAware;
/**
* An pre-authenticated processing filter which extracts (if enabled through
* configuration) the possibility to authenticate a target based on its target
* security-token with the {@code Authorization} HTTP header.
* {@code Example Header: Authorization: TargetToken
* 5d8fSD54fdsFG98DDsa.}
*
* The {@code Authorization} header is a HTTP standard and reverse proxy or
* other proxies will keep the Authorization headers untouched instead of maybe
* custom headers which have then weird side-effects. Furthermore frameworks are
* aware of the sensitivity of the Authorization header and do not log it and
* store it somewhere.
*
*
*
*/
public class HttpControllerPreAuthenticateSecurityTokenFilter extends AbstractHttpControllerAuthenticationFilter {
private final ControllerManagement controllerManagement;
/**
* Constructor.
*
* @param systemManagement
* the system management service to retrieve configuration
* properties
* @param tenantAware
* the tenant aware service to get configuration for the specific
* tenant
* @param controllerManagement
* the controller management to retrieve the specific target
* security token to verify
*/
public HttpControllerPreAuthenticateSecurityTokenFilter(final SystemManagement systemManagement,
final TenantAware tenantAware, final ControllerManagement controllerManagement) {
super(systemManagement, tenantAware);
this.controllerManagement = controllerManagement;
}
@Override
protected PreAuthenficationFilter createControllerAuthenticationFilter() {
return new ControllerPreAuthenticateSecurityTokenFilter(systemManagement, controllerManagement, tenantAware);
}
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* 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.hawkbit.security;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.tenancy.TenantAware;
/**
* Extract the {@code Authorization} header is a HTTP standard and reverse proxy
* or other proxies will keep the Authorization headers untouched instead of
* maybe custom headers which have then weird side-effects. Furthermore
* frameworks are aware of the sensitivity of the Authorization header and do
* not log it and store it somewhere.
*
*
*
*/
public class HttpControllerPreAuthenticatedGatewaySecurityTokenFilter
extends AbstractHttpControllerAuthenticationFilter {
/**
* Constructor.
*
* @param systemManagement
* the system management service to retrieve configuration
* properties
* @param tenantAware
* the tenant aware service to get configuration for the specific
* tenant
*/
public HttpControllerPreAuthenticatedGatewaySecurityTokenFilter(final SystemManagement systemManagement,
final TenantAware tenantAware) {
super(systemManagement, tenantAware);
}
@Override
protected PreAuthenficationFilter createControllerAuthenticationFilter() {
return new ControllerPreAuthenticatedGatewaySecurityTokenFilter(systemManagement, tenantAware);
}
}

View File

@@ -0,0 +1,60 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* 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.hawkbit.security;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.tenancy.TenantAware;
/**
* An pre-authenticated processing filter which extracts the principal from a
* request URI and the credential from a request header.
*
*
*
*/
public class HttpControllerPreAuthenticatedSecurityHeaderFilter extends AbstractHttpControllerAuthenticationFilter {
private final String caCommonNameHeader;
private final String caAuthorityNameHeader;
/**
* Creates a new {@link ControllerPreAuthenticatedSecurityHeaderFilter}, in
* case the HTTP request matches the given pattern the principal is parsed
* from the HTTP request with the given URI pattern, in case the URI pattern
* does not match the current request then only the existence of the
* configured header field is checked.
*
* @param caCommonNameHeader
* the http-header which holds the common-name of the certificate
* @param caAuthorityNameHeader
* the http-header which holds the ca-authority name of the
* certificate
* @param systemManagement
* the system management service to retrieve configuration
* properties to check if the header authentication is enabled
* for this tenant
* @param tenantAware
* the tenant aware service to get configuration for the specific
* tenant
*/
public HttpControllerPreAuthenticatedSecurityHeaderFilter(final String caCommonNameHeader,
final String caAuthorityNameHeader, final SystemManagement systemManagement,
final TenantAware tenantAware) {
super(systemManagement, tenantAware);
this.caCommonNameHeader = caCommonNameHeader;
this.caAuthorityNameHeader = caAuthorityNameHeader;
}
@Override
protected PreAuthenficationFilter createControllerAuthenticationFilter() {
return new ControllerPreAuthenticatedSecurityHeaderFilter(caCommonNameHeader, caAuthorityNameHeader,
systemManagement, tenantAware);
}
}

View File

@@ -0,0 +1,71 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* 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.hawkbit.security;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
/**
* Extracts download or upload id from the request URI secruity token and set
* the security context.
*
*
*
*/
public class HttpDownloadAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
public static final String REQUEST_ID_REGEX_PATTERN = ".*\\/downloadId\\/.*";
private static final Logger LOGGER = LoggerFactory.getLogger(HttpDownloadAuthenticationFilter.class);
private final Pattern pattern;
private final Cache cache;
/**
* Constructor.
*
* @param cache
* the cache
*/
public HttpDownloadAuthenticationFilter(final Cache cache) {
this.cache = cache;
this.pattern = Pattern.compile(REQUEST_ID_REGEX_PATTERN);
}
private Object getDownloadByUri(final String requestURI) {
final Matcher matcher = pattern.matcher(requestURI);
if (!matcher.matches()) {
return null;
}
LOGGER.debug("retrieving id from URI request {}", requestURI);
final String[] groups = requestURI.split("\\/");
final String id = groups[groups.length - 1];
if (id == null) {
return null;
}
return cache.get(id).get();
}
@Override
protected Object getPreAuthenticatedPrincipal(final HttpServletRequest request) {
return getDownloadByUri(request.getRequestURI());
}
@Override
protected Object getPreAuthenticatedCredentials(final HttpServletRequest request) {
return getDownloadByUri(request.getRequestURI());
}
}