-
Notifications
You must be signed in to change notification settings - Fork 261
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6977 from MihaiIliescu/propagate_hhtp_headers_coc…
…o_pharma_example Propagate HTTP headers - Coco Pharma example
- Loading branch information
Showing
7 changed files
with
310 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
.../openmetadata/metadatasecurity/samples/CocoPharmaPlatformSecurityConnectorTokenBased.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
/* SPDX-License-Identifier: Apache 2.0 */ | ||
/* Copyright Contributors to the ODPi Egeria project. */ | ||
package org.odpi.openmetadata.metadatasecurity.samples; | ||
|
||
import io.jsonwebtoken.Claims; | ||
import io.jsonwebtoken.Jws; | ||
import io.jsonwebtoken.Jwts; | ||
import io.jsonwebtoken.security.Keys; | ||
import org.odpi.openmetadata.frameworks.connectors.ffdc.UserNotAuthorizedException; | ||
import org.odpi.openmetadata.http.HttpHeadersThreadLocal; | ||
import org.odpi.openmetadata.metadatasecurity.connectors.OpenMetadataPlatformSecurityConnector; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.util.Base64; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* CocoPharmaPlatformSecurityConnector overrides the default behavior for the security connector | ||
* to allow requests the Coco Pharmaceutical's server administrator APIs. In this example, | ||
* only Gary Geeke is allowed to issue these requests. | ||
* | ||
* To generate a JWT for this example, we used the following payload: | ||
* { | ||
* "sub": "garygeeke", | ||
* "name": "Gary Geeke", | ||
* "actions":["platform-administrator","platform-operator","platform-investigator"], | ||
* "iat": {Epoch timestamp}, | ||
* "exp": {Epoch timestamp} | ||
* } | ||
*/ | ||
public class CocoPharmaPlatformSecurityConnectorTokenBased extends OpenMetadataPlatformSecurityConnector { | ||
private enum PlatformRoles { | ||
PLATFORM_ADMINISTRATOR, | ||
PLATFORM_OPERATOR, | ||
PLATFORM_INVESTIGATOR; | ||
|
||
private String getName() { | ||
return this.toString().toLowerCase(); | ||
} | ||
} | ||
|
||
//secret used to decrypt the given token | ||
private final byte[] secret = Base64.getDecoder().decode("d14uaEwsGU3cXopmxaEDqhQTow81zixFWbFUuu3budQ"); | ||
|
||
private static final Logger log = LoggerFactory.getLogger(CocoPharmaPlatformSecurityConnectorTokenBased.class); | ||
|
||
|
||
/** | ||
* Check that the calling user is authorized to create new servers. | ||
* | ||
* @param userId calling user | ||
* @throws UserNotAuthorizedException the user is not authorized to access this platform | ||
*/ | ||
@Override | ||
public void validateUserForNewServer(String userId) throws UserNotAuthorizedException { | ||
final String methodName = "validateUserForNewServer"; | ||
|
||
if (!isAllowedToPerformAction(userId, PlatformRoles.PLATFORM_ADMINISTRATOR)) { | ||
super.throwUnauthorizedPlatformAccess(userId, methodName); | ||
} | ||
} | ||
|
||
|
||
/** | ||
* Check that the calling user is authorized to issue operator requests to the OMAG Server Platform. | ||
* | ||
* @param userId calling user | ||
* @throws UserNotAuthorizedException the user is not authorized to issue operator commands to this platform | ||
*/ | ||
@Override | ||
public void validateUserAsOperatorForPlatform(String userId) throws UserNotAuthorizedException { | ||
final String methodName = "validateUserAsOperatorForPlatform"; | ||
|
||
if (!isAllowedToPerformAction(userId, PlatformRoles.PLATFORM_OPERATOR)) { | ||
super.throwUnauthorizedPlatformAccess(userId, methodName); | ||
} | ||
} | ||
|
||
|
||
/** | ||
* Check that the calling user is authorized to issue operator requests to the OMAG Server Platform. | ||
* | ||
* @param userId calling user | ||
* @throws UserNotAuthorizedException the user is not authorized to issue diagnostic commands to this platform | ||
*/ | ||
@Override | ||
public void validateUserAsInvestigatorForPlatform(String userId) throws UserNotAuthorizedException { | ||
final String methodName = "validateUserAsInvestigatorForPlatform"; | ||
|
||
if (!isAllowedToPerformAction(userId, PlatformRoles.PLATFORM_INVESTIGATOR)) { | ||
super.throwUnauthorizedPlatformAccess(userId, methodName); | ||
} | ||
} | ||
|
||
private List<String> getUserActionsFromToken(String userId) { | ||
Map<String, String> headersMap = HttpHeadersThreadLocal.getHeadersThreadLocal().get(); | ||
if (headersMap != null && !headersMap.isEmpty()) { | ||
Jws<Claims> jwtClaims = Jwts.parserBuilder() | ||
.setSigningKey(Keys.hmacShaKeyFor(secret)) | ||
.build().parseClaimsJws(headersMap.get("authorization")); | ||
|
||
String username = jwtClaims.getBody().getSubject(); | ||
List<String> actions = jwtClaims.getBody().get("actions", List.class); | ||
if (username.equals(userId) && actions != null && !actions.isEmpty()) { | ||
log.info("User {} validated for issuing requests.", username); | ||
return actions; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
private Boolean isAllowedToPerformAction(String userId, PlatformRoles role) { | ||
List<String> userActions = getUserActionsFromToken(userId); | ||
|
||
if (userActions != null && !userActions.isEmpty() && userActions.contains(role.getName())) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
...i/openmetadata/metadatasecurity/samples/CocoPharmaPlatformSecurityProviderTokenBased.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* SPDX-License-Identifier: Apache 2.0 */ | ||
/* Copyright Contributors to the ODPi Egeria project. */ | ||
package org.odpi.openmetadata.metadatasecurity.samples; | ||
|
||
import org.odpi.openmetadata.frameworks.auditlog.AuditLogReportingComponent; | ||
import org.odpi.openmetadata.frameworks.connectors.properties.beans.ConnectorType; | ||
import org.odpi.openmetadata.metadatasecurity.connectors.OpenMetadataPlatformSecurityProvider; | ||
|
||
/** | ||
* CocoPharmaPlatformSecurityProviderTokenBased is the connector provider to the | ||
* sample platform security connector for the Coco Pharmaceuticals scenarios. | ||
*/ | ||
public class CocoPharmaPlatformSecurityProviderTokenBased extends OpenMetadataPlatformSecurityProvider | ||
{ | ||
/* | ||
* Unique identifier of the connector for the audit log. | ||
*/ | ||
private static final int connectorComponentId = 93; | ||
|
||
/* | ||
* Unique identifier for the connector type. | ||
*/ | ||
private static final String connectorTypeGUID = "5e6f852f-5912-44fb-aa6c-784efe25af47"; | ||
|
||
/* | ||
* Descriptive information about the connector for the connector type and audit log. | ||
*/ | ||
private static final String connectorQualifiedName = "Egeria:Sample:TokenBased:PlatformSecurity:CocoPharmaceuticals"; | ||
private static final String connectorDisplayName = "Coco Pharmaceuticals Platform Security Connector Token Based"; | ||
private static final String connectorDescription = "Connector that exposes the usability of custom authorisation headers for Coco Pharmaceuticals."; | ||
|
||
/* | ||
* Class of the connector. | ||
*/ | ||
private static final Class<?> connectorClass = CocoPharmaPlatformSecurityConnectorTokenBased.class; | ||
|
||
|
||
/** | ||
* Constructor used to initialize the ConnectorProviderBase with the Java class name of the specific | ||
* registry store implementation. | ||
*/ | ||
public CocoPharmaPlatformSecurityProviderTokenBased() | ||
{ | ||
super(); | ||
|
||
/* | ||
* Set up the class name of the connector that this provider creates. | ||
*/ | ||
super.setConnectorClassName(connectorClass.getName()); | ||
|
||
/* | ||
* Set up the connector type that should be included in a connection used to configure this connector. | ||
*/ | ||
ConnectorType connectorType = new ConnectorType(); | ||
connectorType.setType(ConnectorType.getConnectorTypeType()); | ||
connectorType.setGUID(connectorTypeGUID); | ||
connectorType.setQualifiedName(connectorQualifiedName); | ||
connectorType.setDisplayName(connectorDisplayName); | ||
connectorType.setDescription(connectorDescription); | ||
connectorType.setConnectorProviderClassName(this.getClass().getName()); | ||
|
||
super.connectorTypeBean = connectorType; | ||
|
||
/* | ||
* Set up the component description used in the connector's audit log messages. | ||
*/ | ||
AuditLogReportingComponent componentDescription = new AuditLogReportingComponent(); | ||
|
||
componentDescription.setComponentId(connectorComponentId); | ||
componentDescription.setComponentName(connectorQualifiedName); | ||
componentDescription.setComponentDescription(connectorDescription); | ||
|
||
super.setConnectorComponentDescription(componentDescription); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters