Skip to content

Commit

Permalink
Merge pull request #91 from FraunhoferISST/feat/security
Browse files Browse the repository at this point in the history
Feat: Add API Key security
  • Loading branch information
mhellmeier authored Nov 27, 2023
2 parents 3c34ecd + aaaa1fb commit 03eed0a
Show file tree
Hide file tree
Showing 26 changed files with 692 additions and 293 deletions.
14 changes: 7 additions & 7 deletions DEPENDENCIES_BACKEND
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ maven/mavencentral/com.zaxxer/HikariCP/5.0.1, Apache-2.0, approved, clearlydefin
maven/mavencentral/io.micrometer/micrometer-commons/1.11.4, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #9243
maven/mavencentral/io.micrometer/micrometer-observation/1.11.4, Apache-2.0, approved, #9242
maven/mavencentral/io.smallrye/jandex/3.0.5, Apache-2.0, approved, clearlydefined
maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.9, Apache-2.0, approved, #5947
maven/mavencentral/io.swagger.core.v3/swagger-core-jakarta/2.2.9, Apache-2.0, approved, #5929
maven/mavencentral/io.swagger.core.v3/swagger-models-jakarta/2.2.9, Apache-2.0, approved, #5919
maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.15, Apache-2.0, approved, #5947
maven/mavencentral/io.swagger.core.v3/swagger-core-jakarta/2.2.15, Apache-2.0, approved, #5929
maven/mavencentral/io.swagger.core.v3/swagger-models-jakarta/2.2.15, Apache-2.0, approved, #5919
maven/mavencentral/jakarta.activation/jakarta.activation-api/2.1.2, EPL-2.0 OR BSD-3-Clause OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jaf
maven/mavencentral/jakarta.annotation/jakarta.annotation-api/2.1.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.ca
maven/mavencentral/jakarta.inject/jakarta.inject-api/2.0.1, Apache-2.0, approved, clearlydefined
Expand Down Expand Up @@ -67,9 +67,9 @@ maven/mavencentral/org.projectlombok/lombok/1.18.30, MIT AND LicenseRef-Public-D
maven/mavencentral/org.skyscreamer/jsonassert/1.5.1, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.slf4j/jul-to-slf4j/2.0.9, MIT, approved, #7698
maven/mavencentral/org.slf4j/slf4j-api/2.0.9, MIT, approved, #5915
maven/mavencentral/org.springdoc/springdoc-openapi-starter-common/2.1.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springdoc/springdoc-openapi-starter-webmvc-api/2.1.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springdoc/springdoc-openapi-starter-webmvc-ui/2.1.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springdoc/springdoc-openapi-starter-common/2.2.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springdoc/springdoc-openapi-starter-webmvc-api/2.2.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springdoc/springdoc-openapi-starter-webmvc-ui/2.2.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springframework.boot/spring-boot-autoconfigure/3.1.4, Apache-2.0, approved, #9341
maven/mavencentral/org.springframework.boot/spring-boot-configuration-processor/3.1.4, Apache-2.0, approved, #11406
maven/mavencentral/org.springframework.boot/spring-boot-starter-aop/3.1.4, Apache-2.0, approved, #9338
Expand Down Expand Up @@ -106,6 +106,6 @@ maven/mavencentral/org.springframework/spring-test/6.0.12, Apache-2.0, approved,
maven/mavencentral/org.springframework/spring-tx/6.0.12, Apache-2.0, approved, #5926
maven/mavencentral/org.springframework/spring-web/6.0.12, Apache-2.0, approved, #5942
maven/mavencentral/org.springframework/spring-webmvc/6.0.12, Apache-2.0, approved, #5944
maven/mavencentral/org.webjars/swagger-ui/4.18.2, Apache-2.0, approved, #7850
maven/mavencentral/org.webjars/swagger-ui/5.2.0, Apache-2.0, approved, #10221
maven/mavencentral/org.xmlunit/xmlunit-core/2.9.1, Apache-2.0, approved, #6272
maven/mavencentral/org.yaml/snakeyaml/2.2, Apache-2.0 AND (Apache-2.0 OR BSD-3-Clause OR EPL-1.0 OR GPL-2.0-or-later OR LGPL-2.1-or-later), approved, #10232
14 changes: 7 additions & 7 deletions backend/DEPENDENCIES
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ maven/mavencentral/com.zaxxer/HikariCP/5.0.1, Apache-2.0, approved, clearlydefin
maven/mavencentral/io.micrometer/micrometer-commons/1.11.4, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #9243
maven/mavencentral/io.micrometer/micrometer-observation/1.11.4, Apache-2.0, approved, #9242
maven/mavencentral/io.smallrye/jandex/3.0.5, Apache-2.0, approved, clearlydefined
maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.9, Apache-2.0, approved, #5947
maven/mavencentral/io.swagger.core.v3/swagger-core-jakarta/2.2.9, Apache-2.0, approved, #5929
maven/mavencentral/io.swagger.core.v3/swagger-models-jakarta/2.2.9, Apache-2.0, approved, #5919
maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.15, Apache-2.0, approved, #5947
maven/mavencentral/io.swagger.core.v3/swagger-core-jakarta/2.2.15, Apache-2.0, approved, #5929
maven/mavencentral/io.swagger.core.v3/swagger-models-jakarta/2.2.15, Apache-2.0, approved, #5919
maven/mavencentral/jakarta.activation/jakarta.activation-api/2.1.2, EPL-2.0 OR BSD-3-Clause OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jaf
maven/mavencentral/jakarta.annotation/jakarta.annotation-api/2.1.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.ca
maven/mavencentral/jakarta.inject/jakarta.inject-api/2.0.1, Apache-2.0, approved, clearlydefined
Expand Down Expand Up @@ -67,9 +67,9 @@ maven/mavencentral/org.projectlombok/lombok/1.18.30, MIT AND LicenseRef-Public-D
maven/mavencentral/org.skyscreamer/jsonassert/1.5.1, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.slf4j/jul-to-slf4j/2.0.9, MIT, approved, #7698
maven/mavencentral/org.slf4j/slf4j-api/2.0.9, MIT, approved, #5915
maven/mavencentral/org.springdoc/springdoc-openapi-starter-common/2.1.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springdoc/springdoc-openapi-starter-webmvc-api/2.1.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springdoc/springdoc-openapi-starter-webmvc-ui/2.1.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springdoc/springdoc-openapi-starter-common/2.2.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springdoc/springdoc-openapi-starter-webmvc-api/2.2.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springdoc/springdoc-openapi-starter-webmvc-ui/2.2.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.springframework.boot/spring-boot-autoconfigure/3.1.4, Apache-2.0, approved, #9341
maven/mavencentral/org.springframework.boot/spring-boot-configuration-processor/3.1.4, Apache-2.0, approved, #11406
maven/mavencentral/org.springframework.boot/spring-boot-starter-aop/3.1.4, Apache-2.0, approved, #9338
Expand Down Expand Up @@ -106,6 +106,6 @@ maven/mavencentral/org.springframework/spring-test/6.0.12, Apache-2.0, approved,
maven/mavencentral/org.springframework/spring-tx/6.0.12, Apache-2.0, approved, #5926
maven/mavencentral/org.springframework/spring-web/6.0.12, Apache-2.0, approved, #5942
maven/mavencentral/org.springframework/spring-webmvc/6.0.12, Apache-2.0, approved, #5944
maven/mavencentral/org.webjars/swagger-ui/4.18.2, Apache-2.0, approved, #7850
maven/mavencentral/org.webjars/swagger-ui/5.2.0, Apache-2.0, approved, #10221
maven/mavencentral/org.xmlunit/xmlunit-core/2.9.1, Apache-2.0, approved, #6272
maven/mavencentral/org.yaml/snakeyaml/2.2, Apache-2.0 AND (Apache-2.0 OR BSD-3-Clause OR EPL-1.0 OR GPL-2.0-or-later OR LGPL-2.1-or-later), approved, #10232
2 changes: 1 addition & 1 deletion backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ FROM maven:3.8.7-eclipse-temurin-17 as build
RUN mkdir /app
WORKDIR /app
COPY pom.xml .
RUN mvn initialize -f pom.xml
RUN mvn dependency:go-offline

COPY src/ /app/src/
RUN mvn clean package -DskipTests
Expand Down
2 changes: 1 addition & 1 deletion backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<description>PURIS Backend</description>
<properties>
<java.version>11</java.version>
<springdoc.version>2.1.0</springdoc.version>
<springdoc.version>2.2.0</springdoc.version>
<okhttp3.version>2.7.5</okhttp3.version>
<hibernate-validator.version>8.0.0.Final</hibernate-validator.version>
<snakeyaml.version>2.2</snakeyaml.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@
import org.modelmapper.config.Configuration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.context.annotation.Bean;

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
@SpringBootApplication
public class PurisApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public class VariablesService {
private String ownDefaultZipCodeAndCity;
@Value("${own.default.country}")
private String ownDefaultCountry;
@Value("${puris.api.key}")
private String apiKey;


/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,18 @@ public class DataAddressPropertiesDto {
@JsonProperty("type")
@NotNull
private DT_DataAddressTypeEnum type;

/**
* Defines the auth key used in httpProxy e.g. "X-API-KEY"
*/
@JsonProperty("authKey")
@NotNull
private String authKey;

/**
* Defines the auth code used in httpProxy e.g. "some value"
*/
@JsonProperty("authCode")
@NotNull
private String authCode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,16 @@ public JsonNode buildTransferRequestBody(String transferId,
transferNode.set("transferType", transferTypeNode);
transferNode.put("managedResources", false);
propertiesNode = MAPPER.createObjectNode();
// TODO: reminder for EDC 0.5.x: receiverHttpEndpoint - auth key and code still not possible
// https://github.com/eclipse-edc/Connector/blob/main/extensions/control-plane/transfer/transfer-pull-http-dynamic-receiver/src/main/java/org/eclipse/edc/connector/receiver/http/dynamic/HttpDynamicEndpointDataReferenceReceiver.java
propertiesNode.put("receiver.http.endpoint", endpointDataReferenceEndpoint);
// Note: auth-code and header currently can not be set in transfer
// https://github.com/eclipse-edc/Connector/blob/release/0.0.1-20230220.patch1-SNAPSHOT/extensions/control-plane/transfer/transfer-pull-http-dynamic-receiver/src/main/java/org/eclipse/edc/connector/receiver/http/dynamic/HttpDynamicEndpointDataReferenceReceiver.java
// header name for auth
propertiesNode.put("receiver.http.auth-code", variablesService.getApiKey());
// header value for auth
propertiesNode.put("receiver.http.auth-key", "X-API-KEY");
// https://github.com/eclipse-edc/Connector/blob/1a927997d48acd839b68ec89637698166bf6ce46/extensions/control-plane/transfer/transfer-pull-http-receiver/src/main/java/org/eclipse/edc/connector/receiver/http/HttpEndpointDataReferenceReceiverExtension.java#L33
transferNode.set("properties", propertiesNode);

return transferNode;
Expand Down Expand Up @@ -201,6 +210,8 @@ public CreateAssetDto buildCreateAssetDtoForApi(DT_ApiMethodEnum method,
apiDataAddressPropertiesDto.setType(DT_DataAddressTypeEnum.HttpData);
apiDataAddressPropertiesDto.setProxyBody(true);
apiDataAddressPropertiesDto.setProxyMethod(true);
apiDataAddressPropertiesDto.setAuthKey("X-API-KEY");
apiDataAddressPropertiesDto.setAuthCode(variablesService.getApiKey());

DataAddressDto apiDataAddressDto = new DataAddressDto();
apiDataAddressDto.setDataAddressPropertiesDto(apiDataAddressPropertiesDto);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2023 Volkswagen AG
* Copyright (c) 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.eclipse.tractusx.puris.backend.common.security;


import lombok.AllArgsConstructor;
import org.eclipse.tractusx.puris.backend.common.security.logic.ApiKeyAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@AllArgsConstructor
public class SecurityConfig {

private final ApiKeyAuthenticationFilter apiKeyAuthenticationFilter;

/**
* Configuration of API Key Authentication for all routes except docker
*/
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(
// any request in spring context
(authorizeHttpRequests) -> authorizeHttpRequests
.requestMatchers("/stockView/**", "/partners/**", "/materials/**", "/materialpartnerrelations/**", "/product-stock/**", "/edrendpoint/**").authenticated()
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
)
.httpBasic(
AbstractHttpConfigurer::disable
)
.sessionManagement(
(sessionManagement) -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.cors(Customizer.withDefaults());

http.addFilterBefore(apiKeyAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

return http.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2023 Volkswagen AG
* Copyright (c) 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.eclipse.tractusx.puris.backend.common.security.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

import java.util.Collection;

/**
* Authentication holding apiKey as principal and authenticated flag. No authorities given as the key is set per config.
*/
@Getter
@Setter
@AllArgsConstructor
public class ApiKeyAuthentication implements Authentication {

private final String apiKey;
private final boolean authenticatedFlag;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}

@Override
public Object getCredentials() {
return null;
}

@Override
public Object getDetails() {
return null;
}

@Override
public Object getPrincipal() {
return apiKey;
}

@Override
public boolean isAuthenticated() {
return authenticatedFlag;
}

@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

}

@Override
public String getName() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2023 Volkswagen AG
* Copyright (c) 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.eclipse.tractusx.puris.backend.common.security.logic;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.eclipse.tractusx.puris.backend.common.security.domain.ApiKeyAuthentication;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
* Authentication filter that checks if X-API-KEY header is given and set to value from config
*/
@Component
@AllArgsConstructor
public class ApiKeyAuthenticationFilter extends OncePerRequestFilter {

public final String API_KEY_HEADER = "X-API-KEY";
private final ApiKeyAuthenticationProvider apiKeyAuthenticationProvider;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String headerKey = request.getHeader(API_KEY_HEADER);

if (headerKey != null){
ApiKeyAuthentication apiKeyAuthentication = new ApiKeyAuthentication(headerKey, false);
Authentication authenticatedObject = apiKeyAuthenticationProvider.authenticate(apiKeyAuthentication);
SecurityContextHolder.getContext().setAuthentication(authenticatedObject);
}

filterChain.doFilter(request,response);
}
}
Loading

0 comments on commit 03eed0a

Please sign in to comment.