Skip to content

Commit

Permalink
Merge pull request eclipse-tractusx#160 from bci-oss/feature/consume-…
Browse files Browse the repository at this point in the history
…bpn-via-header

feat: Consume bpn via header
  • Loading branch information
tunacicek authored Jul 13, 2023
2 parents a67a5e8 + 5d44506 commit 3789199
Show file tree
Hide file tree
Showing 17 changed files with 101 additions and 237 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/********************************************************************************
* Copyright (c) 2021-2022 Robert Bosch Manufacturing Solutions GmbH
* Copyright (c) 2021-2022 Contributors to the Eclipse Foundation
* Copyright (c) 2021-2023 Robert Bosch Manufacturing Solutions GmbH
* Copyright (c) 2021-2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand Down Expand Up @@ -47,12 +47,6 @@ public static class Idm {
@NotEmpty(message = "public client id must not be empty")
private String publicClientId;

/**
* The tenant id claim name in the jwt token.
*/
@NotEmpty(message = "tenantId claimName must not be empty")
private String tenantIdClaimName;

/**
* The owning tenant id to which this AAS Registry belongs to.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.context.request.NativeWebRequest;

@Service
Expand Down Expand Up @@ -85,18 +86,18 @@ public ResponseEntity<Void> deleteSubmodelDescriptorByIdThroughSuperpath( String

@Override
public ResponseEntity<GetAssetAdministrationShellDescriptorsResult> getAllAssetAdministrationShellDescriptors( Integer limit, String cursor,
AssetKind assetKind, String assetType ) {
AssetKind assetKind, String assetType, @RequestHeader String externalSubjectId ) {
Integer page = 0 ;
Integer pageSize = 100;
ShellCollectionDto dto = shellService.findAllShells(page, pageSize);
ShellCollectionDto dto = shellService.findAllShells(page, pageSize,getExternalSubjectIdOrEmpty(externalSubjectId));
GetAssetAdministrationShellDescriptorsResult result = shellMapper.toApiDto(dto);
return new ResponseEntity<>(result, HttpStatus.OK);
}

@Override
// new todo: correct implementation
public ResponseEntity<GetSubmodelDescriptorsResult> getAllSubmodelDescriptorsThroughSuperpath( String aasIdentifier, Integer limit, String cursor ) {
Shell savedShell = shellService.findShellByExternalId(aasIdentifier);
public ResponseEntity<GetSubmodelDescriptorsResult> getAllSubmodelDescriptorsThroughSuperpath( String aasIdentifier, Integer limit, String cursor, @RequestHeader String externalSubjectId ) {
Shell savedShell = shellService.findShellByExternalId(aasIdentifier, getExternalSubjectIdOrEmpty(externalSubjectId));
Set<Submodel> submodels = savedShell.getSubmodels();
List<SubmodelDescriptor> descriptorResults = submodelMapper.toApiDto( submodels );
GetSubmodelDescriptorsResult result = new GetSubmodelDescriptorsResult();
Expand All @@ -105,8 +106,8 @@ public ResponseEntity<GetSubmodelDescriptorsResult> getAllSubmodelDescriptorsThr
}

@Override
public ResponseEntity<AssetAdministrationShellDescriptor> getAssetAdministrationShellDescriptorById( String aasIdentifier ) {
Shell saved = shellService.findShellByExternalId(aasIdentifier);
public ResponseEntity<AssetAdministrationShellDescriptor> getAssetAdministrationShellDescriptorById( String aasIdentifier, @RequestHeader String externalSubjectId ) {
Shell saved = shellService.findShellByExternalId(aasIdentifier, getExternalSubjectIdOrEmpty(externalSubjectId));
return new ResponseEntity<>(shellMapper.toApiDto(saved), HttpStatus.OK);
}

Expand Down Expand Up @@ -145,18 +146,18 @@ public ResponseEntity<Void> putSubmodelDescriptorByIdThroughSuperpath( String aa

@Override
public ResponseEntity<List<String>> getAllAssetAdministrationShellIdsByAssetLink(List<SpecificAssetId> assetIds,
Integer limit, String cursor) {
Integer limit, String cursor, @RequestHeader String externalSubjectId) {
// TODO: Implement cursor based pag.
if (assetIds == null || assetIds.isEmpty()) {
return new ResponseEntity<>(Collections.emptyList(), HttpStatus.OK);
}
List<String> externalIds = shellService.findExternalShellIdsByIdentifiersByExactMatch(shellMapper.fromApiDto(assetIds));
List<String> externalIds = shellService.findExternalShellIdsByIdentifiersByExactMatch(shellMapper.fromApiDto(assetIds), getExternalSubjectIdOrEmpty(externalSubjectId));
return new ResponseEntity<>(externalIds, HttpStatus.OK);
}

@Override
public ResponseEntity<List<SpecificAssetId>> getAllAssetLinksById(String aasIdentifier) {
Set<ShellIdentifier> identifiers = shellService.findShellIdentifiersByExternalShellId(aasIdentifier);
public ResponseEntity<List<SpecificAssetId>> getAllAssetLinksById(String aasIdentifier, @RequestHeader String externalSubjectId) {
Set<ShellIdentifier> identifiers = shellService.findShellIdentifiersByExternalShellId(aasIdentifier, getExternalSubjectIdOrEmpty(externalSubjectId));
return new ResponseEntity<>(shellMapper.toApiDto(identifiers), HttpStatus.OK);
}

Expand All @@ -168,10 +169,14 @@ public ResponseEntity<List<SpecificAssetId>> postAllAssetLinksById(String aasIde
}

@Override
public ResponseEntity<List<String>> postQueryAllAssetAdministrationShellIds(ShellLookup shellLookup) {
public ResponseEntity<List<String>> postQueryAllAssetAdministrationShellIds(ShellLookup shellLookup, @RequestHeader String externalSubjectId) {
List<SpecificAssetId> assetIds = shellLookup.getQuery().getAssetIds();
List<String> externalIds = shellService.findExternalShellIdsByIdentifiersByAnyMatch(shellMapper.fromApiDto(assetIds));
List<String> externalIds = shellService.findExternalShellIdsByIdentifiersByAnyMatch(shellMapper.fromApiDto(assetIds), getExternalSubjectIdOrEmpty(externalSubjectId));
return new ResponseEntity<>(externalIds, HttpStatus.OK);
}
}

private String getExternalSubjectIdOrEmpty(String externalSubjectId) {
return (null ==externalSubjectId) ? "" : externalSubjectId;
}
}

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/********************************************************************************
* Copyright (c) 2021-2022 Robert Bosch Manufacturing Solutions GmbH
* Copyright (c) 2021-2022 Contributors to the Eclipse Foundation
* Copyright (c) 2021-2023 Robert Bosch Manufacturing Solutions GmbH
* Copyright (c) 2021-2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand All @@ -20,12 +20,8 @@
package org.eclipse.tractusx.semantics.registry.security;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;

import java.util.Collection;
Expand All @@ -51,14 +47,12 @@
*
*/
@Slf4j
public class AuthorizationEvaluator implements TenantAware {
public class AuthorizationEvaluator {

private final String clientId;
private final String tenantClaimName;

public AuthorizationEvaluator(String clientId, String tenantClaimName) {
public AuthorizationEvaluator(String clientId) {
this.clientId = clientId;
this.tenantClaimName = tenantClaimName;
}

public boolean hasRoleViewDigitalTwin() {
Expand Down Expand Up @@ -105,26 +99,6 @@ private boolean containsRole(String role){
return rolesList.contains(role);
}

@Override
public String getTenantId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(!(authentication instanceof JwtAuthenticationToken)){
throw new InvalidBearerTokenException("Authentication method not supported");
}

JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) (authentication);
Map<String, Object> claims = jwtAuthenticationToken.getToken().getClaims();

Object tenantIdFromClaim = claims.get(tenantClaimName);
if(tenantIdFromClaim == null ){
throw new InvalidBearerTokenException(String.format("No claim for %s found.", tenantClaimName));
}
if(!(tenantIdFromClaim instanceof String )){
throw new InvalidBearerTokenException(String.format("Invalid type for Claim %s. Expected type is String.", tenantClaimName));
}
return (String) tenantIdFromClaim;
}

/**
* Represents the roles defined for the registry.
*/
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/********************************************************************************
* Copyright (c) 2021-2022 Robert Bosch Manufacturing Solutions GmbH
* Copyright (c) 2021-2022 Contributors to the Eclipse Foundation
* Copyright (c) 2021-2023 Robert Bosch Manufacturing Solutions GmbH
* Copyright (c) 2021-2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand Down Expand Up @@ -38,9 +38,4 @@ protected SecurityFilterChain configure(HttpSecurity http) throws Exception {
.csrf().disable()
.headers().frameOptions().disable().and().build();
}

@Bean
public TenantAware tenantAware(){
return new NoOpTenantAware();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,12 @@
package org.eclipse.tractusx.semantics.registry.security;

import org.eclipse.tractusx.semantics.RegistryProperties;
import org.eclipse.tractusx.semantics.registry.security.AuthorizationEvaluator;
import org.eclipse.tractusx.semantics.registry.security.JwtTenantIdValidator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtDecoders;
import org.springframework.security.oauth2.jwt.JwtValidators;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;

@Profile("!local")
Expand Down Expand Up @@ -86,20 +73,8 @@ protected SecurityFilterChain configure(HttpSecurity http) throws Exception {
return http.build();
}

@Bean
@ConditionalOnMissingBean
public JwtDecoder jwtDecoder(RegistryProperties registryProps,
OAuth2ResourceServerProperties oauth2Props) {
String issuerUri = oauth2Props.getJwt().getIssuerUri();
NimbusJwtDecoder jwtDecoder = JwtDecoders.fromIssuerLocation(issuerUri);
OAuth2TokenValidator<Jwt> defaultIssuer = JwtValidators.createDefaultWithIssuer(issuerUri);
OAuth2TokenValidator<Jwt> tenantIdValidator = new JwtTenantIdValidator(registryProps.getIdm().getTenantIdClaimName());
jwtDecoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(defaultIssuer, tenantIdValidator));
return jwtDecoder;
}

@Bean
public AuthorizationEvaluator authorizationEvaluator(RegistryProperties registryProperties){
return new AuthorizationEvaluator(registryProperties.getIdm().getPublicClientId(), registryProperties.getIdm().getTenantIdClaimName());
return new AuthorizationEvaluator(registryProperties.getIdm().getPublicClientId());
}
}

This file was deleted.

Loading

0 comments on commit 3789199

Please sign in to comment.