diff --git a/samples/k8s-deploy-and-test.sh b/samples/k8s-deploy-and-test.sh index dc05e3a96a..68443b3c5c 100755 --- a/samples/k8s-deploy-and-test.sh +++ b/samples/k8s-deploy-and-test.sh @@ -64,13 +64,13 @@ prepare_image() { #prepare deployment file and deploy the app, first argument is sample name deploy_app() { - sed "s/.*containers.*/ imagePullSecrets:\n - name: sap-image-registry\n&/; s//${REPOSITORY}\/$1:$VERSION/" ./k8s/deployment.yml | kubectl apply -f - -n "$NAMESPACE" + sed "s/.*containers.*/ imagePullSecrets:\n - name: sap-image-registry\n&/; s//${REPOSITORY}\/$1:$VERSION/" ./k8s/deployment.yml | kubectl apply -f - -n "$NAMESPACE" sleep 30 } #delete the deployed app, first argument is sample name delete_deployment() { - sed "s/.*containers.*/ imagePullSecrets:\n - name: sap-image-registry\n&/; s//${REPOSITORY}\/$1:$VERSION/" ./k8s/deployment.yml | kubectl delete -f - -n "$NAMESPACE" + sed "s/.*containers.*/ imagePullSecrets:\n - name: sap-image-registry\n&/; s//${REPOSITORY}\/$1:$VERSION/" ./k8s/deployment.yml | kubectl delete -f - -n "$NAMESPACE" sleep 7 } diff --git a/samples/spring-security-hybrid-usage/README.md b/samples/spring-security-hybrid-usage/README.md index bb8a6c6e6f..3b00e654c0 100644 --- a/samples/spring-security-hybrid-usage/README.md +++ b/samples/spring-security-hybrid-usage/README.md @@ -1,160 +1,205 @@ -# Description -This sample is a Spring Boot application that utilizes the `spring-security` client library to authenticate JWT tokens issued by either the `xsuaa` service or the `identity` service. -The `xsuaa` service generates an access token, while the `identity` service produces an OIDC token. -The tokens differ in the details they provide through token claims. In both instances, -the validated token is accessible as a [`Token`](/java-api/src/main/java/com/sap/cloud/security/token/Token.java) via the Spring`org.springframework.security.core.context.SecurityContextHolder`. +# SAP BTP Spring Security Client Library Hybrid sample application +This Spring Boot sample application uses the `spring-security` module to validate JWT tokens issued by either the `xsuaa` or the `identity` service. +The `xsuaa` service provides an OAuth access token, while the `identity` service provides an OIDC token. +The tokens differ in the details they provide through token claims. +In both instances, the validated token is accessible as a [`Token`](/java-api/src/main/java/com/sap/cloud/security/token/Token.java) via the Spring`org.springframework.security.core.context.SecurityContextHolder`. + +Additionally, this sample showcases the use of the `CorrelationIdFilter`, which appends a correlation_id to the MDC context. +This is then used to augment subsequent/outgoing requests with an `X-CorrelationID` header. +:link: More information can be found in the [logging filter library documentation](https://github.com/SAP/cf-java-logging-support/wiki/Instrumenting-Servlets). + +## Build and Deploy +### 1. Deploy the application on Cloud Foundry or Kyma/Kubernetes. +
+Deployment on Cloud Foundry + +#### Run maven to compile and package the sample application: +```shell +mvn clean package +``` + +#### Create the XSUAA service instance +Use the cf CLI to create an XSUAA service instance based on the authentication settings in [xs-security.json](xs-security.json). +```shell +cf create-service xsuaa application xsuaa-authn -c xs-security.json +cf create-service xsuaa broker xsuaa-broker -c xs-security-broker.json +``` +:grey_exclamation: The `xsuaa-broker` instance is optional. +Use it if you want to test the application with multiple XSUAA service instances. +You would also need to update the [manifest.yml](https://github.com/SAP/cloud-security-services-integration-library/blob/main/samples/spring-security-hybrid-usage/manifest.yml#L20) with the broker instance information. -Additionally, this sample showcases the use of the `CorrelationIdFilter`, which appends a correlation_id to the MDC context. -This is then used to augment subsequent/outgoing requests with an `X-CorrelationID` header. -For more information about the logging filter library employed, please visit [this link](https://github.com/SAP/cf-java-logging-support/wiki/Instrumenting-Servlets). +#### Create the IAS Service Instance +Use the cf CLI to create an Identity service instance +```shell +cf create-service identity application ias-authn +``` + +#### Configure the manifest +The [vars](../vars.yml) contain hosts and paths that need to be adopted. -Follow the deployment steps for [Kyma/Kubernetes](#deployment-on-kymakubernetes) or [Cloud Foundry](#deployment-on-cloud-foundry). +#### Deploy the application +Deploy the application using the cf CLI. + +```shell +cf push --vars-file ../vars.yml +``` +:warning: This will expect 1 GB of free memory quota. +> Note: As service instance gets created asynchronously, you might get the error `There is an operation in progress for the service instance`. +> In this case, wait a moment and try again. +
-# Deployment on Kyma/Kubernetes
-Expand this to follow the deployment steps - -- Build docker image and push to repository -- Configure the deployment.yml -- Deploy the application -- Admin: Assign Role Collection to your XSUAA user -- Admin: Assign Group to your IAS user -- Access the application - -## Build docker image and push to repository -```shell script -mvn spring-boot:build-image -Dspring-boot.build-image.imageName=/ -docker push / +Deployment on Kubernetes + +#### Build and tag docker image and push to repository +Execute the following commands to build and push the docker image to a repository. +Replace `/` with your repository and image name. +```shell +mvn spring-boot:build-image -Dspring-boot.build-image.imageName=/ +docker push / ``` -> This makes use of `Dockerfile`. -## Configure the deployment.yml -In deployment.yml replace the image repository placeholder `` with the one created in the previous step. +#### Configure the deployment.yml +In deployment.yml replace the placeholder `` with the image tag created in the previous step. + +:warning: If you are [using a private repository](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/), +you also need to provide the image pull secret in the deployment.yml. -If you want to test the app with multiple Xsuaa bindings (application and broker plan) uncomment the following lines: -- [Service Instance definition and the binding](https://github.com/SAP/cloud-security-services-integration-library/blob/main/samples/spring-security-hybrid-usage/k8s/deployment.yml#L39-L72) +:bulb: If you want to test the app with multiple Xsuaa bindings (application and broker plan) uncomment the following lines: +- [Service Instance definition and the binding](https://github.com/SAP/cloud-security-services-integration-library/blob/main/samples/spring-security-hybrid-usage/k8s/deployment.yml#L39-L71) - [Volume mount for the service instance secret](https://github.com/SAP/cloud-security-services-integration-library/blob/main/samples/spring-security-hybrid-usage/k8s/deployment.yml#L127-L129) - [Volume for the service instance secret](https://github.com/SAP/cloud-security-services-integration-library/blob/main/samples/spring-security-hybrid-usage/k8s/deployment.yml#L138-L140) -## Deploy the application -Deploy the application using [kubectl cli](https://kubernetes.io/docs/reference/kubectl/) -```shell script -kubectl apply -f ./k8s/deployment.yml -n +#### Deploy the application +Deploy the application using [kubectl](https://kubernetes.io/docs/reference/kubectl/). +```shell +kubectl apply -f k8s/deployment.yml ``` +
-## Cockpit administration task: Assign Xsuaa Role Collection to your User -Finally, as part of your Identity Provider, e.g. SAP ID Service, assign the deployed Role Collection `XSUAA-Viewer` to your user as depicted in the screenshot below and as documented [here](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/9e1bf57130ef466e8017eab298b40e5e.html). - -![](../images/SAP_CP_Cockpit_AssignRoleCollectionToUser.png) - -Further up-to-date information you can get on sap.help.com: -- [Maintain Role Collections](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/d5f1612d8230448bb6c02a7d9c8ac0d1.html) -- [Maintain Roles for Applications](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/7596a0bdab4649ac8a6f6721dc72db19.html). - -## IAS User administration task: Assign Group to your User -You need administrator permissions to create Groups "Read" in IAS and assign it to your user.
See also [SAP Help: "Creating a User Group"](https://help.sap.com/viewer/a339f23ec736441abb2e187b7a7b6afb/LATEST/en-US/64544f432cd24b8589707a5d8a2b3e2e.html). - -## Access the application -1. Follow [HowToFetchToken](../../docs/HowToFetchToken.md) guide to fetch IAS and XSUAA tokens. - 1. Get an IAS oidc token via ``password`` grant token flow. - You can get the information to fill the placeholders from the service binding secret: - ```shell script - kubectl get secret "ias-service-binding" -o go-template='{{range $k,$v := .data}}{{"### "}}{{$k}}{{"\n"}}{{$v|base64decode}}{{"\n\n"}}{{end}}' -n - ``` - 2. Get a XSUAA access token via ``client-certificate`` token flow. - You can get the information to fill the placeholders from the service binding secret: - ```shell script - kubectl get secret "xsuaa-service-binding" -o go-template='{{range $k,$v := .data}}{{"### "}}{{$k}}{{"\n"}}{{$v|base64decode}}{{"\n\n"}}{{end}}' -n - ``` -2. In the Kyma Console, go to `` - `Discovery and Network` - `API Rules`. Copy the host entry of the `spring-security-hybrid-api` api rule. - -3. Call the following endpoints with ```Authorization``` header = "Bearer " - - `/sayHello` - GET request that provides token details, but only if token provides expected read permission (scope/groups). - - `/method` - GET request executes a method secured with Spring Global Method Security, user requires read permission (scope/groups). - - :bulb: If you call the same endpoint without `Authorization` header you should get a `401`. - -## Cleanup -Finally, delete your application and your service instances using the following command: -```shell script - kubectl delete -f ./k8s/deployment.yml -n -``` - +### 3. Give permission to user +To get access to the sample application, you need a user with one of the following assigned: +- the role collection `Sample Viewer (spring-security-hybrid-usage)' (via XSUAA) +- the group `Read` (via IAS) +:bulb: You can postpone this step if you first want to test the application without the required authorization. + +#### Assign Role Collection (XSUAA) +This can be done in the SAP BTP Cockpit or using the btp CLI. + +
+Assign role collection via cockpit +In the cockpit navigate to your subaccount. +To assign the role collection of the sample application to a user you have basically two options: + +1. Navigate to the user by clicking on `Security` -> `Users`, + select the user and click on `Assign Role Collection` + (more info at [help.sap.com](https://help.sap.com/docs/btp/sap-business-technology-platform/find-users-and-their-role-collection-assignments)). +2. Navigate to the role collection by clicking on `Security` -> `Role Collections`, + select `Sample Viewer (spring-security-hybrid-usage)`, + click on `Edit` to add the user and finish by clicking on `Save` + (more info at [help.sap.com](https://help.sap.com/docs/btp/sap-business-technology-platform/assign-users-to-role-collections)). +
-# Deployment on Cloud Foundry -To deploy the application, the following steps are required: -- Create an XSUAA service instance -- Create an Identity service instance -- Configure manifest.yml -- Compile and deploy the application -- Admin: Assign Role Collection to your XSUAA user -- Admin: Assign Group to your IAS user -- Access the application +
+Assign role collection via command line +To assign the role collection to a user via the [btp CLI](https://help.sap.com/docs/btp/sap-business-technology-platform/account-administration-using-sap-btp-command-line-interface-btp-cli), +you need to [log in to your global account](https://help.sap.com/docs/btp/btp-cli-command-reference/btp-login) and execute the following command: -## Create the XSUAA Service Instance -Use the [xs-security.json](./xs-security.json) to define the X.509 authentication method with Xsuaa managed certificate and create a service instance. ```shell -cf create-service xsuaa broker xsuaa-broker -c xs-security.json #optional -cf create-service xsuaa application xsuaa-authn -c xs-security.json +btp assign security/role-collection "Sample Viewer (spring-security-hybrid-usage)" --subaccount --to-user ``` -:grey_exclamation: Xsuaa broker instance is optional. Use it if you want to test the application with multiple Xsuaa Service instances. -You would also need to update the [manifest.yml](https://github.com/SAP/cloud-security-services-integration-library/blob/main/samples/spring-security-hybrid-usage/manifest.yml#L19) with the broker instance information. +
-## Create the IAS Service Instance -Use the ias service broker and create an identity service instance +#### Assign group (IAS) +You need administrator permissions to create group `Read` in IAS and assign it to a user. +:link: More information can be found at [SAP Help: "Creating a User Group"](https://help.sap.com/viewer/a339f23ec736441abb2e187b7a7b6afb/LATEST/en-US/64544f432cd24b8589707a5d8a2b3e2e.html). + +### 4. Access the application +The sample application provides three HTTP endpoints: + +- `/sayHello` - authorized access only +- `/comp/sayHello` - authorized access only +- `/method` - authorized access only (executes a method secured with Spring Global Method Security) + +Before sending requests to the above endpoints we need to obtain a valid XSUAA access token or OIDC token for a user. +To this we need to retrieve credentials for the bound XSUAA and IAS service instances from Cloud Foundry or Kubernetes. + +
+Retrieve credentials from Cloud Foundry + +Either use the cockpit to navigate to your application (via subaccount and space) and click on 'Environment Variables' or use the cf CLI command ```shell -cf create-service identity application ias-authn +cf env spring-security-hybrid-usage ``` +to retrieve the application environment. +The environment variable `VCAP_SERVICES` contains `credentials` sections for the `xsuaa` and `ìdentity` service instances. +
-## Configure the manifest -The [vars](../vars.yml) contains hosts and paths that you might need to adopt. - -## Compile and deploy the application -Deploy the application using cf push. It will expect 1 GB of free memory quota. +
+Retrieve credentials from Kubernetes +Use the following Kubernetes CLI commands to retrieve the `xsuaa` and `ìdentity` service instance credentials. ```shell -mvn clean package -cf push --vars-file ../vars.yml +kubectl get secret "xsuaa-authn-binding" -o go-template='{{range $k,$v := .data}}{{"### "}}{{$k}}{{"\n"}}{{$v|base64decode}}{{"\n\n"}}{{end}}' +kubectl get secret "xsuaa-broker-binding" -o go-template='{{range $k,$v := .data}}{{"### "}}{{$k}}{{"\n"}}{{$v|base64decode}}{{"\n\n"}}{{end}}' +kubectl get secret "ias-service-binding" -o go-template='{{range $k,$v := .data}}{{"### "}}{{$k}}{{"\n"}}{{$v|base64decode}}{{"\n\n"}}{{end}}' ``` -> Note: In case of this error message `An operation for service instance ias-authn is in progress.` wait a moment, as identity service instance gets created asynchronously. +
-## Cockpit administration task: Assign Xsuaa Role Collection to your User -Finally, as part of your Identity Provider, e.g. SAP ID Service, assign the deployed Role Collection(s) such as `XSUAA-Viewer` to your user as depicted in the screenshot below and as documented [here](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/9e1bf57130ef466e8017eab298b40e5e.html). +Use the credentials to retrieve an XSUAA OAuth access token or OIDC id token for the sample application by following the [HowToFetchToken](../../docs/HowToFetchToken.md) guide. -![](../images/SAP_CP_Cockpit_AssignRoleCollectionToUser.png) +Now you can use the tokens to access the application via curl. -Further up-to-date information you can get on sap.help.com: -- [Maintain Role Collections](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/d5f1612d8230448bb6c02a7d9c8ac0d1.html) -- [Maintain Roles for Applications](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/7596a0bdab4649ac8a6f6721dc72db19.html). +
+access Cloud Foundry deployment -## IAS User administration task: Assign Group to your User -You need administrator permissions to create a Groups "Read" in IAS and assign it to your user. +``` +curl -X GET \ +https://spring-security-hybrid-usage-<>.<>/sayHello \ +-H 'Authorization: Bearer <>' +``` -## Access the application -1. Follow [HowToFetchToken](../../docs/HowToFetchToken.md) guide to fetch IAS and XSUAA tokens. - 1. Get an IAS oidc token via ``password`` grant token flow. - You can get the information to fill the placeholders from your system environment `cf env spring-security-hybrid-usage` -> ``VCAP_SERVICES``.`identity` - 2. Get a XSUAA access token via ``client-certificate`` token flow. - You can get the information to fill the placeholders from your system environment `cf env spring-security-hybrid-usage` -> ``VCAP_SERVICES``.`xsuaa` +:bulb: You can check the logs using the following cf CLI command: +```shell +cf logs spring-security-hybrid-usage --recent +``` +
-2. Call the following endpoints with ```Authorization``` header = "Bearer " - - `https://spring-security-hybrid-usage-./sayHello` - GET request that provides token details, but only if token provides expected read permission (scope/groups). - - `https://spring-security-hybrid-usage-./method` - GET request executes a method secured with Spring Global Method Security, user requires read permission (scope/groups). +
+access Kubernetes deployment - :bulb: If you call the same endpoint without `Authorization` header you should get a `401`. +In the Kyma Console, go to your namespace and navigate to `Discovery and Network` → `API Rules`. +Copy the host entry of the `spring-security-hybrid-api` api rule. -3. Have a look into the logs with: - ```shell - cf logs spring-security-hybrid-usage --recent - ``` +```shell +curl -X GET \ +https://<>/sayHello \ +-H 'Authorization: Bearer <>' +``` +
+ +:bulb: If you call the same endpoints without `Authorization` header you should get a `HTTP 401` response. -## Clean-Up +### 5. Cleanup +If you no longer need the sample application, you can free up resources using the cf CLI or the Kubernetes CLI. + +
+Cleanup commands for Cloud Foundry -Finally delete your application and your service instances using the following commands: ```shell +cf unbind-service spring-security-hybrid-usage ias-authn cf delete -f spring-security-hybrid-usage cf delete-service -f xsuaa-authn -cf delete-service -f xsuaa-broker # optional +cf delete-service -f xsuaa-broker cf delete-service -f ias-authn ``` +
+ +
+Cleanup command for Kubernetes + +```shell + kubectl delete -f k8s/deployment.yml +``` +
diff --git a/samples/spring-security-hybrid-usage/k8s/deployment.yml b/samples/spring-security-hybrid-usage/k8s/deployment.yml index 0a7c90b5f7..2a8424f44d 100644 --- a/samples/spring-security-hybrid-usage/k8s/deployment.yml +++ b/samples/spring-security-hybrid-usage/k8s/deployment.yml @@ -16,15 +16,15 @@ spec: - x509 scopes: - name: "$XSAPPNAME.Read" - description: Read Permissions. + description: Scope for spring-security-hybrid-usage sample application role-templates: - name: Viewer - description: View Data + description: Role for spring-security-hybrid-usage sample application scope-references: - "$XSAPPNAME.Read" role-collections: - - name: XSUAA-Viewer - description: Viewer (read) + - name: "Sample Viewer (spring-security-hybrid-usage)" + description: Role collection for spring-security-hybrid-usage sample application role-template-references: - "$XSAPPNAME.Viewer" --- @@ -42,7 +42,7 @@ spec: # name: xsuaa-broker #spec: # serviceOfferingName: xsuaa -# servicePlanName: application +# servicePlanName: broker # parameters: # xsappname: spring-security-hybrid-usage # tenant-mode: dedicated @@ -51,15 +51,15 @@ spec: # - x509 # scopes: # - name: "$XSAPPNAME.Read" -# description: Read Permissions. +# description: Scope for spring-security-hybrid-usage sample application # role-templates: # - name: Viewer -# description: View Data +# description: Role for spring-security-hybrid-usage sample application # scope-references: # - "$XSAPPNAME.Read" # role-collections: -# - name: XSUAA-Viewer -# description: Viewer (read) +# - name: "Sample Viewer via broker (spring-security-hybrid-usage)" +# description: Role collection for spring-security-hybrid-usage broker access # role-template-references: # - "$XSAPPNAME.Viewer" #--- @@ -111,7 +111,7 @@ spec: kyma-grafana: enabled spec: containers: - - image: + - image: env: - name: SERVICE_BINDING_ROOT value: "/bindings" diff --git a/samples/spring-security-hybrid-usage/manifest.yml b/samples/spring-security-hybrid-usage/manifest.yml index bb235bf0a4..06c6ecaa77 100644 --- a/samples/spring-security-hybrid-usage/manifest.yml +++ b/samples/spring-security-hybrid-usage/manifest.yml @@ -5,7 +5,6 @@ # configured for EU10. For other landscapes, please adopt LANDSCAPE_APPS_DOMAIN in ../vars.yml # If the route is occupied, you might need to change ID in ../vars.yml applications: -# The sample application. - name: spring-security-hybrid-usage instances: 1 memory: 896M @@ -18,6 +17,7 @@ applications: JBP_CONFIG_OPEN_JDK_JRE: '{jre: { version: 17.0.+ }}' services: - name: xsuaa-authn +# - name: xsuaa-broker - name: ias-authn parameters: { "credential-type": "X509_GENERATED" } diff --git a/samples/spring-security-hybrid-usage/pom.xml b/samples/spring-security-hybrid-usage/pom.xml index 559278128e..e907af5aa3 100644 --- a/samples/spring-security-hybrid-usage/pom.xml +++ b/samples/spring-security-hybrid-usage/pom.xml @@ -104,6 +104,13 @@ org.springframework.boot spring-boot-maven-plugin + + + + ${java.version} + + + org.apache.maven.plugins diff --git a/samples/spring-security-hybrid-usage/xs-security-broker.json b/samples/spring-security-hybrid-usage/xs-security-broker.json new file mode 100644 index 0000000000..753b6f102d --- /dev/null +++ b/samples/spring-security-hybrid-usage/xs-security-broker.json @@ -0,0 +1,32 @@ +{ + "xsappname": "spring-security-hybrid-usage", + "description": "SAP BTP Spring Security Client Library Hybrid sample application", + "tenant-mode": "dedicated", + "oauth2-configuration": { + "credential-types": ["x509"] + }, + "scopes": [ + { + "name": "$XSAPPNAME.Read", + "description": "Scope for spring-security-hybrid-usage sample application" + } + ], + "role-templates": [ + { + "name": "Viewer", + "description": "Role for spring-security-hybrid-usage sample application", + "scope-references": [ + "$XSAPPNAME.Read" + ] + } + ], + "role-collections": [ + { + "name": "Sample Viewer via broker (spring-security-hybrid-usage)", + "description": "Role collection for spring-security-hybrid-usage broker access", + "role-template-references": [ + "$XSAPPNAME.Viewer" + ] + } + ] +} diff --git a/samples/spring-security-hybrid-usage/xs-security.json b/samples/spring-security-hybrid-usage/xs-security.json index bbb099b3f2..70e813fd38 100644 --- a/samples/spring-security-hybrid-usage/xs-security.json +++ b/samples/spring-security-hybrid-usage/xs-security.json @@ -1,5 +1,6 @@ { "xsappname": "spring-security-hybrid-usage", + "description": "SAP BTP Spring Security Client Library Hybrid sample application", "tenant-mode": "dedicated", "oauth2-configuration": { "credential-types": ["x509"] @@ -7,13 +8,13 @@ "scopes": [ { "name": "$XSAPPNAME.Read", - "description": "Read Permissions." + "description": "Scope for spring-security-hybrid-usage sample application" } ], "role-templates": [ { "name": "Viewer", - "description": "View Data", + "description": "Role for spring-security-hybrid-usage sample application", "scope-references": [ "$XSAPPNAME.Read" ] @@ -21,8 +22,8 @@ ], "role-collections": [ { - "name": "XSUAA-Viewer", - "description": "Viewer (read)", + "name": "Sample Viewer (spring-security-hybrid-usage)", + "description": "Role collection for spring-security-hybrid-usage sample application", "role-template-references": [ "$XSAPPNAME.Viewer" ]