Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/maven/org.apache.maven.plugins-ma…
Browse files Browse the repository at this point in the history
…ven-source-plugin-3.3.0
  • Loading branch information
finkmanAtSap authored Aug 15, 2023
2 parents 235af56 + 46ee394 commit 1e6e19f
Show file tree
Hide file tree
Showing 42 changed files with 413 additions and 95 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
# Change Log
All notable changes to this project will be documented in this file.

## 3.1.2
- [token-client]
- `OAuth2ServiceException` has been extended with getter method `getHeaders()` that gives the access to failed request's response headers
- `XsuaaOAuth2TokenService` and `DefaultOAuth2TokenService` add the response headers and status code to the thrown `OAuth2ServiceException`

## 3.1.1
- [env]
- ``ServiceBindingEnvironment`` has been extended with a method `getServiceConfigurationsAsList()` that returns a list of all available service configurations parsed from environment
- in case of multiple service configurations of the same service plans `ServiceBindingEnvironment.getXsuaaConfiguration()` and `ServiceBindingEnvironment.getServiceConfigurations()` will return the first one from the list.
This adjustment ensures that the logic is in line with the 2.x major version.
- [token-client] reverted removal of ``OAuth2ServiceException.getHttpStatusCode()``

#### Dependency upgrades
- Bump [com.sap.cloud.environment.servicebinding:java-bom](https://github.com/SAP/btp-environment-variable-access) from 0.8.0 to 0.9.0

## 3.1.0
#### :exclamation: IMPORTANT Update
The `zone_uuid` claim in Identity service tokens has been deprecated and is now replaced by the `app_tid` claim. You should use the `app_tid` claim to identify the unique tenant id, which was previously referred to as the zone.
Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

# SAP BTP Security Services Integration Libraries
This repository offers a comprehensive set of libraries designed to simplify the integration of [SAP Business Technology Platform](https://www.sap.com/products/technology-platform.html) (SAP BTP) security services (XSUAA and Identity Services).
Tailored to support Java EE and Spring Boot applications running on Cloud Foundry or Kubernetes environments.
Tailored to support Jakarta EE and Spring Boot applications running on Cloud Foundry or Kubernetes environments.
The libraries focus on streamlining [OAuth 2.0](https://oauth.net) access token validation for tokens issued by XSUAA and Identity Services. In addition, it offers a token-client library to easily fetch tokens without cumbersome setup for http requests. Finally, it offers testing utility that mocks Xsuaa and Identity service behaviour and makes it easy to write integration and unit tests.

## Table of Contents
1. [Prerequisites](#prerequisites)
2. [Usage](#usage)
- [2.1 Token Validation](#21-token-validation)
- [2.1.1 Java EE web applications](#211-Java-EE-web-applications)
- [2.1.1 Jakarta EE web applications](#211-Jakarta-EE-web-applications)
- [2.1.2 Spring Boot applications](#212-spring-boot-web-applications)
- [2.2 Token Flows](#22-token-flows-for-token-retrievals)
- [2.3 Testing utilities](#23-testing-utilities)
Expand Down Expand Up @@ -51,10 +51,10 @@ Key features:
* Automatic OAuth2 service configuration based on SAP BTP service bindings found in the environment
* OAuth2 Token Validation based on these service configurations
* Easy access to principal and token claims within request handlers
* Automatic or sample integrations for common web application frameworks (i.e. Java EE / Spring Security)
* Automatic or sample integrations for common web application frameworks (i.e. Jakarta EE / Spring Security)

#### 2.1.1. Java EE web applications
Developers who need OAuth2 token validation and token access in their Java EE applications can utilize the [java-security](./java-security) library. This library simplifies the process of acquiring token information such as principal and audiences from the security context and takes over token validation for tokens issued by Xsuaa or Identity services.
#### 2.1.1. Jakarta EE web applications
Developers who need OAuth2 token validation and token access in their Jakarta EE applications can utilize the [java-security](./java-security) library. This library simplifies the process of acquiring token information such as principal and audiences from the security context and takes over token validation for tokens issued by Xsuaa or Identity services.
This library is also integrated in SAP Java Buildpack.

In the table below you'll find links to detailed information.
Expand Down Expand Up @@ -97,7 +97,7 @@ In the table below you'll find links to detailed information.

| Library | Usage Examples |
|-------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [token-client](/token-client) | [java-tokenclient-usage](samples/java-tokenclient-usage) demonstrates usage of token client library in Java EE application<br/> [spring-security-xsuaa-usage](samples/spring-security-xsuaa-usage) demonstrates usage in Spring Boot application |
| [token-client](/token-client) | [java-tokenclient-usage](samples/java-tokenclient-usage) demonstrates usage of token client library in Jakarta EE application<br/> [spring-security-xsuaa-usage](samples/spring-security-xsuaa-usage) demonstrates usage in Spring Boot application |

### 2.3 Testing utilities
For authentication/authorization flow testing purposes there is [java-security-test](/java-security-test) library at your disposal that can be used for unit and integration tests to test the Xsuaa or Identity service client functionality in the application.
Expand All @@ -107,14 +107,14 @@ With this library you can test end to end all your secured endpoints or app logi
Key features:
* Generates and signs tokens with user provided attributes
* Provides a pre-configured local authorization server that mocks communication with the BTP security services to validate self-generated tokens
* For Java EE application sets up a local application server that is pre-configured with a security filter matching self-generated tokens. It can be configured to serve the servlets you want to test with mocked authorization
* For Jakarta EE application sets up a local application server that is pre-configured with a security filter matching self-generated tokens. It can be configured to serve the servlets you want to test with mocked authorization


In the table below you'll find links to detailed information.

| Library | Usage Examples |
|-------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [java-security-test](/java-security-test) | [Integration test code snippet](/samples/spring-security-hybrid-usage/src/test/java/sample/spring/security/junitjupiter/TestControllerIasTest.java) for Spring application <br/>[Integration test code snippet](/samples/java-security-usage/src/test/java/com/sap/cloud/security/samples/HelloJavaServletIntegrationTest.java) for Java EE web.xml based servlets <br/> [Integration test code snippet](/samples/java-security-usage-ias/src/test/java/com/sap/cloud/security/samples/ias/HelloJavaServletIntegrationTest.java) for Java EE annotation based servlets <br/> |
| [java-security-test](/java-security-test) | [Integration test code snippet](/samples/spring-security-hybrid-usage/src/test/java/sample/spring/security/junitjupiter/TestControllerIasTest.java) for Spring application <br/>[Integration test code snippet](/samples/java-security-usage/src/test/java/com/sap/cloud/security/samples/HelloJavaServletIntegrationTest.java) for Jakarta EE web.xml based servlets <br/> [Integration test code snippet](/samples/java-security-usage-ias/src/test/java/com/sap/cloud/security/samples/ias/HelloJavaServletIntegrationTest.java) for Jakarta EE annotation based servlets <br/> |

## Installation
The SAP Cloud Security Services Integration is published to maven central: https://search.maven.org/search?q=com.sap.cloud.security and is available as a Maven dependency. Add the following BOM to your dependency management in your `pom.xml`:
Expand All @@ -124,7 +124,7 @@ The SAP Cloud Security Services Integration is published to maven central: https
<dependency>
<groupId>com.sap.cloud.security</groupId>
<artifactId>java-bom</artifactId>
<version>3.1.0</version>
<version>3.1.2</version>
<scope>import</scope>
<type>pom</type>
</dependency>
Expand Down
2 changes: 1 addition & 1 deletion bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<groupId>com.sap.cloud.security</groupId>
<artifactId>java-bom</artifactId>
<version>3.1.0</version>
<version>3.1.2</version>
<packaging>pom</packaging>
<name>java-bom</name>

Expand Down
2 changes: 1 addition & 1 deletion env/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<parent>
<groupId>com.sap.cloud.security.xsuaa</groupId>
<artifactId>parent</artifactId>
<version>3.1.0</version>
<version>3.1.2</version>
</parent>

<groupId>com.sap.cloud.security</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import com.sap.cloud.security.json.DefaultJsonObject;

import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
Expand All @@ -33,7 +31,7 @@
public class ServiceBindingEnvironment implements Environment {
private final ServiceBindingAccessor serviceBindingAccessor;
private UnaryOperator<String> environmentVariableReader = System::getenv;
private Map<Service, Map<ServiceConstants.Plan, OAuth2ServiceConfiguration>> serviceConfigurations;
private Map<Service, List<OAuth2ServiceConfiguration>> serviceConfigurations;

/**
* Uses the
Expand Down Expand Up @@ -80,17 +78,20 @@ public ServiceBindingEnvironment withEnvironmentVariableReader(UnaryOperator<Str
@Nullable
@Override
public OAuth2ServiceConfiguration getXsuaaConfiguration() {
return Stream
.of(ServiceConstants.Plan.APPLICATION, ServiceConstants.Plan.BROKER, ServiceConstants.Plan.SPACE,
ServiceConstants.Plan.DEFAULT)
.map(plan -> getServiceConfigurations().get(XSUAA).get(plan))
.filter(Objects::nonNull)
.findFirst().orElse(null);
List<ServiceConstants.Plan> orderedServicePlans = List.of(ServiceConstants.Plan.APPLICATION, ServiceConstants.Plan.BROKER,
ServiceConstants.Plan.SPACE, ServiceConstants.Plan.DEFAULT);
List<OAuth2ServiceConfiguration> xsuaaConfigurations = getServiceConfigurationsAsList().get(XSUAA);

return xsuaaConfigurations.stream()
.filter(config -> getServicePlan(config) != null)
.filter(config -> orderedServicePlans.contains(getServicePlan(config)))
.min(Comparator.comparingInt(config -> orderedServicePlans.indexOf(getServicePlan(config))))
.orElse(null);
}

@Override
public int getNumberOfXsuaaConfigurations() {
return getServiceConfigurations().get(XSUAA).size();
return getServiceConfigurationsAsList().get(XSUAA).size();
}

/**
Expand Down Expand Up @@ -119,16 +120,50 @@ public OAuth2ServiceConfiguration getIasConfiguration() {
* Gives access to all service configurations parsed from the environment. The
* service configurations are parsed on the first access, then cached.
*
* @return the service configurations grouped first by service, then by service
* plan.
* @return the service configurations grouped by service
*/
public Map<Service, List<OAuth2ServiceConfiguration>> getServiceConfigurationsAsList() {
if (serviceConfigurations == null) {
this.readServiceConfigurations();
}

return this.serviceConfigurations;
}

/**
* Gives access to all service configurations parsed from the environment. The
* service configurations are parsed on the first access, then cached.
*
* Note that the result contains only one service configuration per service plan and does not contain configurations
* with a service plan other than those from {@link ServiceConstants}#Plan.
* Use {@link ServiceBindingEnvironment#getServiceConfigurationsAsList()} to get a complete list of configurations.
*
* @return the service configurations grouped first by service, then by service plan.
*/
@Override
public Map<Service, Map<ServiceConstants.Plan, OAuth2ServiceConfiguration>> getServiceConfigurations() {
if (serviceConfigurations == null) {
this.readServiceConfigurations();
}

return serviceConfigurations;
Map<Service, Map<ServiceConstants.Plan, OAuth2ServiceConfiguration>> result = new EnumMap<>(Service.class);

for (Map.Entry<Service, List<OAuth2ServiceConfiguration>> entry : serviceConfigurations.entrySet()) {
Service service = entry.getKey();
List<OAuth2ServiceConfiguration> configurations = entry.getValue();

Map<ServiceConstants.Plan, OAuth2ServiceConfiguration> planConfigurations = configurations.stream()
.filter(config -> getServicePlan(config) != null)
.collect(Collectors.toMap(
config -> ServiceConstants.Plan.from(config.getProperty(SERVICE_PLAN)),
Function.identity(),
(a, b) -> a
));

result.put(service, planConfigurations);
}

return result;
}

/** Parses the service configurations from the environment. */
Expand All @@ -142,9 +177,7 @@ private void readServiceConfigurations() {
.filter(Objects::nonNull)
.map(builder -> builder.runInLegacyMode(runInLegacyMode()))
.map(OAuth2ServiceConfigurationBuilder::build)
.collect(
Collectors.toMap(config -> ServiceConstants.Plan.from(config.getProperty(SERVICE_PLAN)),
Function.identity()))));
.toList()));
}

/**
Expand All @@ -156,6 +189,15 @@ private void clearServiceConfigurations() {
this.serviceConfigurations = null;
}

@Nullable
private ServiceConstants.Plan getServicePlan(OAuth2ServiceConfiguration config) {
try {
return ServiceConstants.Plan.from(config.getProperty(SERVICE_PLAN));
} catch(IllegalArgumentException e) {
return null;
}
}

private boolean runInLegacyMode() {
String vcapApplicationJson = environmentVariableReader.apply(VCAP_APPLICATION);

Expand Down
Loading

0 comments on commit 1e6e19f

Please sign in to comment.