SAP-samples / SAP-samples/ams-samples-java

ams-spring-boot-shopping: `/products` always returns 403

Open
#99 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
0
Forks
0
Avg merge
2d 15h
Merged PRs (30d)
5

Description

Summary

In ams-spring-boot-shopping, calling GET /products (and GET /privileges) with a valid IAS token is rejected with HTTP 403, even though the app is bound, token is valid, policies are pushed.

Steps to reproduce

  1. Deploy the sample as single-tenant IAS app on CF. Bind the app to a IAS app, create app2app trust, create client credentials for the consumer app.
  2. Obtain a valid IAS token for the consumer app. Make sure to hit the right dependency. Should look like [1]
  3. curl -H "Authorization: Bearer <token>" https://<app>/products

Expected: 200 with the product list (the GetProducts API maps to internal.GetProductsshopping.ReadProductsGRANT read ON products).
Actual: 403.

Root cause

The request is authenticated but no AMS principal is ever established, so the AMS authorization check runs against empty authorizations and denies.

SecurityConfiguration#filterChain wires the resource server with:

https://github.com/SAP-samples/ams-samples-java/blob/10e80968de39c73cafe70f83fc30ced2b0c72b31/ams-spring-boot-shopping/src/main/java/com/sap/cloud/security/ams/samples/config/SecurityConfiguration.java#L62

With the default converter, Spring produces a plain org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken whose principal is a plain org.springframework.security.oauth2.jwt.Jwt, not a SAP com.sap.cloud.security.spring.token.authentication.AuthenticationToken.

The cloud-security JavaSecurityContextHolderStrategy only copies the SAP Token into com.sap.cloud.security.token.SecurityContext when the Spring Authentication's principal is a SAP Token. Because it isn't, SecurityContext.getToken() stays null, so com.sap.cloud.security.ams.api.Principal.fromSecurityContext() returns null, and SciAuthorizationsProvider short-circuits to empty authorizations. Every @CheckPrivilege then evaluates granted=false → 403. Logs here [2].

Direction for a fix

The app needs a jwtAuthenticationConverter that turns the validated IAS Jwt into a SAP AuthenticationToken, so the AMS principal is established. Worked for me afterwards.

[1]

{
  "ias_apis": [
    "GetProducts"
  ],
  "sub": "consumer",
  "aud": "ams-secured-app",
  "app_tid": "app-tid",
  "sap_id_type": "app",
  "azp": "consumer",
  "iss": "https://iasid.ondemand.com",
  "azpacr": "1",
  "exp": 1787302610,
  "iat": 1787299010,
  "jti": "096f3ac5-adf2-4516-845b-dd295afbfab0"
}

[2]

IasJwtDecoder            : The token of service IAS was successfully validated.
BearerTokenAuthenticationFilter : Set SecurityContextHolder to JwtAuthenticationToken
    [Principal=org.springframework.security.oauth2.jwt.Jwt@..., Granted Authorities=[]]
SciAuthorizationsProvider : No principal provided. Using empty authorizations.
...
horizationManagerBeforeMethodInterceptor : Failed to authorize ... ProductsService.getProducts()
    ... result AuthorizationDecision [granted=false]

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in ams-spring-boot-shopping/src/main/java/com/sap/cloud/security/ams/samples/config/SecurityConfiguration.java at SecurityConfiguration#filterChain. Reproduce the request with a valid IAS token, then inspect how the resource server converts the Jwt before AMS authorization runs. Done means the AMS principal is established and GET /products and GET /privileges return the expected authorized responses instead of 403.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring-boot
Domain
api, authentication, backend, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.