This library serves as slim client for some XSUAA /oauth/token
token endpoints as specified here.
Furthermore it introduces a new API to support the following token flows:
- User Token Flow.
The idea behind a User Token exchange is to separate service-specific access scopes into separate tokens. For example, if Service A has scopes specific to its functionality and Service B has other scopes, the intention is that there is no single Jwt token that contains all of these scopes. - Client Credentials Flow.
The Client Credentials (RFC 6749, section 4.4) is used by clients to obtain an access token outside of the context of a user. It is used for non interactive applications (a CLI, a batch job, or for service-2-service communication) where the token is issued to the application itself, instead of an end user for accessing resources without principal propagation. - Refresh Token Flow.
A Refresh Token (RFC 6749, section 1.5) flow allows you to obtain a new access token in case the current one becomes invalid or expires.
Note: The Authorization Code Grant Flow involves the browser and is therefore triggered by an API gateway (e.g. Application Router). The other flows, however, may need to be triggered programmatically, e.g. to exchange one token for another or refresh a token, if it is about to expire. When you create a XSUAA service instance a OAuth client gets created and you receive the client credentials (client id and secret) when you bind your application with the XSUAA service instance. Having that in place you are ready to use the token flows in your Java application.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>com.sap.cloud.security.xsuaa</groupId>
<artifactId>token-client</artifactId>
<version>2.0.0</version>
</dependency>
In context of a Spring Boot application you may like to leverage auto-configuration:
<dependency>
<groupId>com.sap.cloud.security.xsuaa</groupId>
<artifactId>xsuaa-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
As auto-configuration requires Spring Boot specific dependencies, it is enabled when using xsuaa-spring-boot-starter
Spring Boot Starter.
Then, xsuaa integration libraries auto-configures beans, that are required to initialize the Token Flows API.
Auto-configuration class | Description |
---|---|
XsuaaAutoConfiguration | Adds xsuaa.* properties to Spring's Environment. The properties are by default parsed from VCAP_SERVICES system environment variables and can be overwritten by properties such as xsuaa.url e.g. for testing purposes. Furthermore it exposes a XsuaaServiceConfiguration bean that can be used to access xsuaa service information. Alternatively you can access them with @Value annotation e.g. @Value("${xsuaa.url:}") String xsuaaBaseUrl . As of version 1.7.0 it creates a default RestTemplate bean that serves as Rest client that is used inside a default OAuth2TokenService to perform HTTP requests to the XSUAA server. It is recommended to overwrite this default and configuring it with the HTTP client of your choice. |
XsuaaTokenFlowAutoConfiguration | Configures a XsuaaTokenFlows bean with a RestOperations and XsuaaServiceConfiguration bean to fetch the XSUAA service binding information. |
You can gradually replace auto-configurations as explained here.
The flows themselves provide a builder-pattern API that allows applications to easily create and execute each flow, guiding developers to only set properties that are relevant for the respective token flow.
To consume the XsuaaTokenFlows
class, you simply need to @Autowire
it like this:
@Autowired
private XsuaaTokenFlows xsuaaTokenFlows;
Or, alternatively you can instantiate it like that
String clientId = "<<client id from XSUAA service binding>>";
String clientSecret = "<<client secret from XSUAA service binding>>";
String xsuaaBaseUrl = "<<xsuaa base url from XSUAA service binding>>";
OAuth2ServiceEndpointsProvider endpointsProvider = new XsuaaDefaultEndpoints(xsuaaBaseUrl);
ClientCredentials clientCredentials = new ClientCredentials(clientId, clientSecret);
RestOperations restOperations = new RestTemplate();
XsuaaTokenFlows tokenFlows = new XsuaaTokenFlows(restOperations, endpointsProvider, clientCredentials);
Obtain a client credentials token:
OAuth2TokenResponse clientCredentialsToken = tokenFlows.clientCredentialsTokenFlow()
.subdomain(jwtToken.getSubdomain()) // this is optional
.execute();
In case you have a refresh token and want to obtain an access token:
OAuth2TokenResponse refreshToken = tokenFlows.refreshTokenFlow()
.refreshToken("<<Your refresh token goes here.>>")
.subdomain(jwtToken.getSubdomain()) // this is optional
.execute();
In order to exchange a user token for another user access token:
XsuaaToken jwtToken = SpringSecurityContext.getToken();
OAuth2TokenResponse userToken = tokenFlows.userTokenFlow()
.token("<<Your current User access token goes here.>>")
.clientId("other's client id") // this is optional
.subdomain(jwtToken.getSubdomain()) // this is optional
.attributes(additionalAttributes) // this is optional
.execute();
Make sure to read the API documentation of the XsuaaTokenFlows
API, to understand what the individual token flows' parameters are for.
Also note, that the user token flow requires an input token that has the scope uaa.user
to succeed.
Have a look at TestController.java
for sample code.