You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/Libraries/java/cap-ams.md
+122-8Lines changed: 122 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,8 @@
2
2
3
3
This `cap-ams` module integrates AMS with CAP Java applications.
4
4
5
+
See the [CAP Integration](/CAP/Basics) documentation for the relationship between cds annotations and enforcement with authorization policies.
6
+
5
7
## Installation
6
8
7
9
Use the Spring Boot starter module:
@@ -17,18 +19,130 @@ Use the Spring Boot starter module:
17
19
For non-Spring-Boot CAP Java applications, please open a support ticket to discuss integration options. The `cap-ams` module does not require Spring Boot, but it is tough to provide a flexible starter with replaceable, configurable bootstrapping without Spring's dependency injection and configuration features.
18
20
:::
19
21
20
-
## Auto-Configuration
22
+
## Architecture
21
23
22
-
The starter automatically configures:
24
+
### Auto-Configured Beans
23
25
24
-
-`AuthorizationManagementService` bean from SAP Identity Service binding
25
-
- CAP authorization integration for automatic role computation and AMS filter annotations
26
-
- Request-scoped `CdsAuthorizations` proxy for manual authorization checks of the current user
27
-
- Readiness state integration (via `spring-boot-starter-ams-readiness`)
26
+
The starter creates the following beans:
28
27
29
-
## CAP Authorization Integration
30
28
31
-
See the [CAP Integration](/CAP/Basics) documentation for the relationship between cds annotations and enforcement with authorization policies.
|`AuthorizationManagementService`| Core AMS client created from the SAP Identity Service binding |
43
+
|`AuthorizationsProvider<CdsAuthorizations>`| Builds and (weakly) caches user authorizations based on UserInfo and SecurityContext (**Customization of library typically happens via this interface**)|
44
+
|`CdsAuthorizations` (Proxy) | Singleton for performing authorization checks in the context of the current user's authorizations |
45
+
|`AmsUserInfoProvider` (Internal) | CAP `UserInfoProvider` implementation that enriches `UserInfo` with cds roles granted by policies |
46
+
|`AmsAuthorizationHandler` (Internal) | CAP event handler that injects instance-based WHERE conditions into `cds restrictions` in case of policy conditions for the computed role(s) |
47
+
|`AmsCdsRouteSecurity`| Provides route-level authorization filters outside CAP framework |
48
+
49
+
### CdsAuthorizations
50
+
51
+
The `CdsAuthorizations`**bean** is a *singleton JDK Dynamic Proxy* that implements the `CdsAuthorizations`**interface**. Every method invocation on the proxy resolves the current user's authorizations with the `AuthorizationsProvider` bean based on the thread-local `RequestContext` and the corresponding `UserInfo`. Additional information is obtained from the thread-local `SecurityContext` if necessary, e.g. whether an SCI or XSUAA token has been used for authentication. This proxy mechanism makes authorization checks against the `CdsAuthorizations` interface very convenient, even though internally one instance of `CdsAuthorizations` is created and cached per request context.
52
+
53
+
54
+
::: warning
55
+
Avoid using the `CdsAuthorizations` bean for custom authorization checks unless necessary. It is best practice to use a declarative approach with cds annotations to let the AMS plugin handle role computation and filter generation while CAP handles the actual authorization enforcement based on the result.
56
+
:::
57
+
58
+
#### Interface
59
+
60
+
The `CdsAuthorizations` interface extends the generic `Authorizations` interface with additional utility methods specific for the [role-based](/CAP/Basics.html#role-policies) CAP integration.
61
+
62
+
It can be used in any Spring context, e.g. custom service handlers, to check for authorizations if the annotation-based approach via the cds model is not sufficient:
privateCdsAuthorizations cdsAuthorizations; // singleton proxy — resolves per request
74
+
75
+
// Showcases a custom service handler that manually checks role permissions for a single-entity access. The example may not showcase best practices, but it serves to illustrate how to use the CdsAuthorizations proxy in custom code if necessary.
// decision.isGranted() — user may use Editor role for this book
95
+
// !decision.isDenied() && !decision.isGranted() — policy condition could not be evaluated to boolean with given input -> unexpected behavior that requires trouble-shooting
96
+
}
97
+
}
98
+
```
99
+
100
+
#### Caching Implementation
101
+
102
+
- The proxy uses `RequestContext.getCurrent(cdsRuntime)` to obtain the current request context and corresponding `UserInfo`. Then, it retrieves the current user's authorizations from the `AuthorizationsProvider` bean, which computes the authorizations based on the `UserInfo` and `SecurityContext`.
103
+
104
+
-`SciAuthorizationsProvider`, the default implementation of `AuthorizationsProvider`, caches computed authorizations in a `WeakHashMap` keyed by the `RequestContext` lifecycle reference — so within a single request, authorizations are resolved only once.
105
+
- The `AmsUserInfoProvider` runs earlier (during `RequestContext` construction) to add AMS roles to `UserInfo`. To prevent a recursive stack overflow, it does not compute user roles with the `CdsAuthorizations` proxy (which would request the `UserInfo` again - forming a cyclic dependency). Instead, it presents the previous `UserInfo` to the `AuthorizationsProvider`.
106
+
107
+
### AmsCdsRouteSecurity
108
+
109
+
`AmsCdsRouteSecurity` provides Spring Security `AuthorizationManager` instances for route-level role checks with Spring Security outside the CAP framework.
110
+
111
+
::: warning
112
+
Avoid using the `AmsCdsRouteSecurity` bean for custom authorization checks unless necessary. It is recommended to use a declarative approach with cds annotations to enforce authorization of application logic. The bean is meant for use cases where this is not practical.
113
+
:::
114
+
115
+
`AmsCdsRouteSecurity` operates on the `CdsAuthorizations` proxy and offers two semantics:
116
+
117
+
-**`checkRole(role)`** — grants access only if the role is unconditionally granted (no conditions). Rejects conditional and denied decisions.
118
+
-**`precheckRole(role)`** — grants access if the role is not definitely denied (i.e., granted or conditional). Use this only when the service layer implements an additional contextual authorization check that enforces the filter conditions.
119
+
120
+
Multi-role variants `checkAnyRole`, `checkAllRoles`, `precheckAnyRole`, and `precheckAllRoles` combine multiple role checks with OR/AND semantics respectively.
The `.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))` call configures Spring Security to validate incoming Bearer tokens as JWTs. This is required for any application that receives OAuth2 tokens (from SAP Identity Service / IAS). Without it, Spring Security will not extract the authenticated principal from the `Authorization` header, and no `SecurityContext` will be available for downstream AMS checks.
143
+
144
+
CAP Java applications that use `cds-starter-cloudfoundry` or `cds-starter-k8s` typically get this configured automatically. You only need to declare it explicitly if you provide a custom `SecurityFilterChain` bean (which overrides the auto-configured one).
0 commit comments