Overview
OAuth2 is the authorization service for YaaS. It implements the OAuth 2.0 framework and provides account authentication and authorization with the use of access tokens. Access tokens allow you to interact with resources in YaaS and support data separation for tenant-aware services.
Key features of the YaaS OAuth2 service:
- issues access tokens (authorization grant)
- authenticates the resource owner
- the
/revoke
endpoint revokes access tokens and refresh tokens - the
/userinfo
endpoint returns information about the authenticated user - the
/tokeninfo
endpoint returns information encoded in access tokens
The OAuth2 service issues tokens with these authorization grants:
- Authorization Code Grant
- Implicit Grant
- Client Credentials Grant
- Resource Owner Password Credentials Grant [DEPRECATED]
For more information, see the Grants section.
API Reference
/revoke
Use this endpoint to revoke tokens.
For more information, see the OAuth 2.0 specification (rfc7009).
/revoke
Revokes the specified tokens. You can revoke both access tokens and refresh tokens.
If you want to revoke multiple tokens at the same time, you can include many tokens in a single request. Your call can include both access tokens and refresh tokens. The OAuth2 service automatically recognizes the type of each token included in the call.
If the token you want to revoke is issued for an authenticated client, the client that requests for that access token to be revoked must be authenticated as well. This means that the authorization header is mandatory in such scenario.
Each client can revoke only the tokens issued for that client.
If your call includes tokens issued for an authenticated client and tokens that do not require authentication, the OAuth2 service revokes all tokens that do not require the client to be authenticated, and returns a code 401
error response.
/authorize
Use this endpoint to authenticate, and obtain an authorization code or an access token.
For more information, see the OAuth 2.0 specification (rfc6749#section-3.1) and Getting Started tutorial.
/authorize
/token
Use this endpoint to obtain an access token for a client.
For more information, see the OAuth 2.0 specification (rfc6749#section-3.2) and Getting Started tutorial.
/token
Get an access token for a client. Use one of the following authorization types:
- [RECOMMENDED] Authorization header.
- client_id and client_secret body parameters. Remove the content of the prefilled example when you use this authorization type.
Examples:
- Client Credentials grant
curl -X POST 'https://api.eu.yaas.io/hybris/oauth2/v1/token' \ -d 'grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&scope=scope1' \ -H 'content-type: application/x-www-form-urlencoded'
- Authorization Code grant (exchange the code for an access token)
curl -X POST 'https://api.eu.yaas.io/hybris/oauth2/v1/token' \ -d 'grant_type=authorization_code&redirect_uri=REDIRECT_URI&code=CODE' \ -H 'content-type: application/x-www-form-urlencoded' -H "Authorization: Basic CLIENT_BASIC_AUTH"
- Authorization Code grant (refresh an access token)
curl -X POST 'https://api.eu.yaas.io/hybris/oauth2/v1/token' \ -d 'grant_type=refresh_token&refresh_token=REFRESH_TOKEN&scope=scope1' \ -H 'content-type: application/x-www-form-urlencoded' -H "Authorization: Basic CLIENT_BASIC_AUTH"
/userinfo
Use the OpenID UserInfo endpoint to retrieve claims about the authenticated end user.
For more information, see the UserInfo Endpoint - OpenId Connect Core 1.0 Specification (section 5.3).
/userinfo
Returns claims about the authenticated end user.
Returns claims about the authenticated end user.
/refreshtokens
Use this endpoint to manage refresh tokens issued for the given user.
/refreshtokens
Returns a list of refresh tokens issued for the given user.
Security/Access Control To access this method, access token must be issued for the user that sends the request.
Deletes refresh tokens issued for the given user.
Security/Access Control To access this method, access token must be issued for the user that sends the request.
/tokeninfo
Use this endpoint to obtain information about your token
/tokeninfo
When the query parameters access_token is provided, this endpoint returns tenant, scopes, allowedServices, etc. associated with the access token.
/end_session
Use this endpoint to terminate user session in SAP Cloud Identity.
/end_session
Terminate the session of the client with the specified client_id.
This endpoint does not terminate the ID token, meaning that such ID token is still valid until its TTL expires. Therefore, the application is able to fetch new access tokens using given ID token. It is highly recommended to remove the ID token in the application after terminating the user session.
Events
The topic owner client is: hybris.authorization
Type | Description | Schema | Payload Example |
---|---|---|---|
subscriptionCreated | The subscription has been created and processed by the OAuth2 authorization provider. | subscriptionCreated_v3 |
|
subscriptionCancelled | The subscription has been cancelled and processed by the OAuth2 authorization provider. | subscriptionCancelled_v1 |
|
These events are deprecated:
Type | Description | Schema | Payload Example |
---|---|---|---|
subscriptionCreated | The subscription has been created and processed by the OAuth2 authorization provider. | subscriptionCreated_v2 |
|
subscriptionCreated | The subscription has been created and processed by the OAuth2 authorization provider. | subscriptionCreated_v1 |
|
Scopes in OAuth2 Service
This table lists the OAuth2 service-specific scopes:
Scope | Description |
---|---|
hybris.tenant | Use this scope to specify the tenant for which an access token is issued. |
hybris.no_tenant | Use this scope to obtain an access token outside the scope of any tenant. |
hybris.org | Use this scope to specify the organization for which an access token is issued. |
For more general information about scopes, see the Scopes section of the Security documentation.
Tokens
Access Token Expiration
Access tokens are valid for one hour. After this time, the access token expires. When you try to call the service using a token that expired, the service returns an error 401
status code, as shown in the example:
{
"status": 401,
"message": "Unauthorized: Bearer TOKEN is invalid",
"type": "insufficient_credentials",
"moreInfo": "https://api.yaas.io/patterns/errortypes.html"
}
If your access token expires, you must obtain a new access token using the appropriate authentication flow.
Refresh Tokens
When you use the Authorization Code Grant, you get a refresh token. Refresh tokens are long-lasting credentials which you can use to fetch additional access tokens. You can request for new access tokens until you have a valid refresh token. Refresh tokens don't expire until you revoke them.Use the
/refreshtokens
endpoint of the OAuth2 service to manage refresh tokens issued for the user. This endpoint allows you to delete all tokens issued for the given user, or to obtain a list of all tokens issued for the given user. When deleting or calling for the list of all refresh tokens, you can additionally filter the list of the tokens by the client for which the tokens are issued.Only an authenticated user can call this endpoint. The service allows to manage only the tokens issued for the user that is the author of the call and whose access token is provided in the authorization header. Use the available query parameters to additionally filter the tokens by the client application for which the tokens are issued.
Revoke a Token
Use the/revoke
endpoint of the OAuth2 service to revoke refresh tokens and access tokens issued for the client.You can send a single request that includes both of the token types at the same time. The service recognizes the type of each token included in the call.
When the token is issued for an authenticated client, only the client for which the token is issued can revoke it.
This means that client A can only request to revoke the tokens issued for client A. Client A cannot request to revoke any tokens issued for the client B. Therefore, the authorization header is mandatory when requesting to revoke tokens issued for authenticated clients.
If a call to the
/revoke
endpoint includes both tokens issued for an authenticated client and tokens fetched without authentication, but does not include the authorization header, the service revokes the tokens fetched without authorization and returns a code 401
error.For more information about the
/revoke
endpoint, see the OAuth2 service API console.This is an example of a request to revoke tokens, with added line breaks for better readability:
curl -X POST 'https://api.eu.yaas.io/hybris/oauth2/v1/revoke' /
-u "CLIENT_ID:CLIENT_SECRET" /
-F token=092i9c9kc09jf082jvm1823jrfcc9i09id0,b9n81en98rn298nf28nf8nncjnw1909
For more information about authorization flows, see the Grants section.
Grants
The OAuth2 service issues tokens with these authorization flows:
- Authorization Code Grant - This flow is for clients that require an authorized user, and is optimized for confidential clients.
- Implicit Grant - This flow is for clients that require an authorized user, or cannot keep credentials secret, such as JavaScript applications.
- Client Credentials Grant - This flow is for server-side clients that do not require an authorized user, such as a service.
- Resource Owner Password Credentials Grant (DEPRECATED) - This flow requires a trusted relationship between the resource owner and the client. The only supported identity provider is YaaS. This flow is deprecated.
yaas
value of the hybris_id_provider parameter is deprecated.popup
value of the display parameter is deprecated.Please refer to the detailed descriptions of the authorization flows for information about the impact of the deprecation and available alternatives.
Authorization code grant
This is a redirection-based flow. The client must be able to interact with the resource owner's user-agent, typically a web browser. The client must also be able to receive requests from the authorization server through redirection. For more information, see the OAuth 2.0 framework.
Register your client's redirect URI in the Builder and obtain the respective value of the client_id.
- To find the Redirect URI, go to the Builder: Projects > {My Project} > Clients > {My Client}.
- To find the Client ID, go to the Builder: Projects > {My Project} > Clients > {My Client} > Client Authorization. Click SHOW to see the value of Client ID
The Authorization Code Grant flow allows you to get an access token by following these steps:
1. Start the flow
curl -i -X GET '<a href="https://api.eu.yaas.io/hybris/oauth2/v1/authorize?response_type=code&client_id=CLIENT_ID&scope=SCOPE_NAME&state=STATE">https://api.eu.yaas.io/hybris/oauth2/v1/authorize?response_type=code&client_id=CLIENT_ID&scope=SCOPE_NAME&state=STATE</a>'
Parameters:
- response_type: (Required) For the Authorization Grant flow, set the value to
code
- client_id: (Required) Provide the client ID from the Client Authorization data.
- scope: This lists the scopes that your client requires to work. Supported predefined scopes are:
- hybris.tenant=$tenant - The user is signed in with the context of a given tenant. To successfully sign in, the user must be a member of the specified tenant.
- hybris.no_tenant - The user is signed in without a tenant context.
- hybris.org=$organizationId - The organization ID for which a token is issued. You cannot use hybris.no_tenant and hybris.tenant when you set this parameter.
- openid - Use this scope if you want to get an ID token. You receive an ID token in the response, after a successful exchange of the authorization code for an access token.
- If the user is not a member of any tenant, the service returns an error message.
- If the user is a member of the tenant that owns the client, the authorization server chooses this tenant automatically and signs in the user within its context.
- If the user is not a member of the tenant that owns the client, the service returns an error message.
If you don't specify any of the parameters, the authorization server, by default, signs in the user within the context of the tenant that owns the client. - redirect_uri: (Recommended) This is the client URL that handles the redirect from the
authorize
endpoint with an authorization code or authorization error. Use the Transport Layer Security (TLS). This parameter is mandatory if multiple redirect URIs (callback URLs) are registered, and it must match at least one of the URLs. Use this parameter even when only a single redirect URI is registered to avoid security issues. - state: (Recommended) Any string that can be used to restore a client state after the redirect. Use this parameter to prevent cross-site request forgery. Parameter value example:
state=security_token%3DSECURE_RANDOM_TOKEN%26custom_state%3Dhttps://yourpage.com
- hybris_id_provider: This is the identity provider registered in YaaS. If you don't specify the value of this parameter, the service uses the default identity provider. You can use the ID of the custom identity provider that the Identity service generates, or one of the predefined values:
sap
- Use this value for SAP Cloud Identity. This is the default identity provider.yaas
- (DEPRECATED) use this value for YaaS identity provider.
- display: This parameter defines the way the authorization server displays the authentication screen to the end user. The supported values change depending on the selected hybris_id_provider.
- When you select the
sap
identity provider, the only supported value ispage
. If you set the the value topopup
or set no value at all, the service uses thepage
parameter by default. - When you select the
yaas
identity provider (DEPRECATED), the supported values arepopup
(DEPRECATED) andpage
.
- When you select the
- hybris-session-id: This is the session identifier. It is generated if it is not passed. When the client calls the service using the YaaS API Proxy, the session ID is set in the header automatically. If the header is set by the client explicitly, it has precedence over the value that the YaaS API Proxy sets.
- code_challenge: This is the PKCE code challenge string. Use a plain, non-encoded string or a BASE64URL-ENCODE(SHA256(ASCII(code_verifier))).
- code_challenge_method: This is the method of code challenge transformation for the PKCE mechanism. If you don't pass it, the service uses the default value. Supported values:
plain
for a plain, non-encoded string; this is the default valueS256
for a BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
The system redirects the user to the sign-in page, where the user provides the email address and password. After the system authenticates the user, the service verifies whether the user is a member of the project and has the required scopes. If the system successfully authenticates and authorizes the user, the service returns the redirect response with an authorization code in the URL query string. Otherwise, the service generates a bad request response or a redirect response with an error parameter in the URL fragment.
2. Exchange the access code for an access token
curl -i -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic CLIENT_BASIC_AUTH" -X POST -d "grant_type=authorization_grant&code=CODE&scope=SCOPE_NAME&redirect_uri=REDIRECT_URI" <a href="https://api.beta.yaas.io/hybris/oauth2/v1/token">https://api.beta.yaas.io/hybris/oauth2/v1/token</a>
Parameters:
- grant_type: (Required)
authorization_code
- code: The authorization code you received in the response for the previous request
- scope: A space-separated list of scopes (URL-encoded) that your client requires to function correctly. For example, you can use the hybris.tenant={tenantName} scope for multi-tenant clients, whether services or Builder modules. If you do not provide it or pass it as hybris.no_tenant, the system uses the identifier of the client's parent tenant. The hybris.org parameter is not supported.
- client_id: The client ID value from the client authorization data
- redirect_uri: The same redirect URI used in the request to fetch the authorization code
- code_verifier: The code verifier value must match the code_challenge value sent in the authorization request after the OAuth2 service transforms it using the method chosen in the authorization request.
200
with the access token included in the response body:3. Refresh the access token
curl -i -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic CLIENT_BASIC_AUTH" -X POST -d "grant_type=refresh_token&refresh_token=REFRESH_TOKEN&scope=SCOPE_NAME" https://api.beta.yaas.io/hybris/oauth2/v1/token
Parameters:
- grant_type: (Required)
refresh_token
- refresh_token: The refresh token issued earlier for the client
- scope: A space-separated list of scopes (URL-encoded) that your client requires to function correctly. The token you get in this process cannot have more permissions than the original access token.
200
with the access token included in the body: For more information, see the OAuth 2.0 framework.PKCE - Proof Key for Code Exchange
In the Authorization Code Grant flow you can use the Proof Key for Code Exchange (PKCE) extension to increase the security of the flow. It is recommended to use PKCE when the flow works with mobile devices or clients which can't store secrets in a secure manner.
To use the PKCE mechanism, include the code_challenge parameter in the authorization request. The code_challenge can be either a plain, non-encoded string, or a BASE64URL-ENCODE(SHA256(ASCII(code_verifier))). Using the additional code_challenge_method parameter you can choose the method of transforming the code challenge:
plain
for a plain, non-encoded stringS256
for a BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
plain
.The OAuth2 service verifies the code when the client calls the /token
endpoint and attempts to exchange the authorization code for an access token. You must pass the code_verifier which the OAuth2 service verifies against the code_challenge value it received in the authorization request.
To verify the request, the OAuth2 transforms the value of the code_verifier parameter using the same transformation method as in the authorization request. The value the service gets as a result of such a transformation must be the same as the value of the code_challenge parameter.
To learn more about PKCE, read the related section of the OAuth2 specification.
Implicit grant
Clients that cannot keep credentials secret in the code, and operate within the scope of the authorized user, should use the OAuth 2.0 Implicit Grant flow. For more information, see the OAuth 2.0 framework.
Register your client's redirect URI in the Builder and obtain the respective value of the client_id.
- To find the Redirect URI, go to Projects > {My Project} > Clients > {My Client}. The Redirect URI is in the Details section.
- To find the Client ID, go to Projects > {My Project} > Clients > {My Client} > Client Authorization. Click SHOW to reveal the value of Client ID that is required for this tutorial.
The Implicit Grant flow allows you to get an access token, optionally with an id_token, in a single step. To get a token, send the following request:
curl -i -X GET 'https://api.beta.yaas.io/hybris/oauth2/v1/authorize?response_type=token&client_id=CLIENT_ID&scope=SCOPE_NAME&state=STATE&redirect_uri=REDIRECT_URI'
Parameters:
- response_type: (Required) For the Implicit Grant flow, set the value to
token
orid_token token
. Request for an id_token to use the Single Sign-On (SSO). - client_id: (Required) Client ID value from the Client Authorization data.
- scope: This lists the scopes that your client requires to work. Supported predefined scopes are:
- hybris.tenant=$tenant - The user is signed in within the context of a given tenant.
- hybris.no_tenant - The user is signed in without a tenant context.
- hybris.org=$organizationId - The organization ID for which a token will be issued. You cannot provide hybris.org with hybris.no_tenant or hybris.tenant at the same time.
If you don't specify any of the parameters, the authorization server, by default, checks how many tenants are associated with the user.- If the user is not a member of any tenant, the service returns an error message.
- If the user is a member of only one tenant, the authorization server chooses this tenant automatically and the user is signed in within its context.
- redirect_uri: (Recommended) This is the client URL that handles the redirect from the
/authorize
endpoint with an authorization code or authorization error. Use the Transport Layer Security (TLS). This parameter is mandatory if you register multiple redirect URIs (callback URLs). It must match at least one of the URLs. To avoid security issues, use this parameter at all times, even if you register only one redirect URI. - state: (Recommended) Any string that can be used to restore a client state after the redirect. Use this parameter to prevent cross-site request forgery.
Expand the following section to see a complete OpenID Connect authentication URI with line breaks added for better readability:
- nonce: This is required if the response type is
id_token token
. It is a unique and usually random string that identifies each request. For more information, see the OpenID Connect 1.0 specification. - hybris_id_provider: This is the identity provider registered in YaaS. If you don't specify the value of this parameter, the service uses the default identity provider. You can use the ID of the custom identity provider that the Identity service generates, or one of the predefined values:
sap
- Use this value for SAP Cloud Identity. This is the default identity provider.yaas
(DEPRECATED) - Use this value for YaaS identity provider.
- display: This parameter defines the way the authorization server displays the authentication screen to the end user. The supported values change depending on the hybris_id_provider you select.
- When you select the
sap
identity provider, the only supported value ispage
. If you set the the value topopup
or set no value at all, the service uses thepage
value by default. - When you select the
yaas
identity provider (DEPRECATED), the supported values arepopup
(DEPRECATED) andpage
.
- When you select the
- hybris-session-id: This is a session identifier. It is generated if it is not passed.
For more information, see the OAuth 2.0 framework.
Client credentials grant
Use the Client Credentials Grant flow for server-side code that uses APIs and for clients that do not require an authenticated user. In this flow, you get an access token without human interaction.
- For a client, go to Projects > {Your Project} > Clients > {Your Client} and click SHOW.
- For a service, go to Projects > {Your Project} > Services > {Your Service} > Client > {Your client} > Client Authorization and click SHOW.
- For a Builder module, go to Projects > {Your Project} > Builder Modules > {Your Builder Module} > Client Authorization and click Unlock.
To obtain the access token, send the following request:
curl -i -H "Content-Type: application/x-www-form-urlencoded" -X POST -d "grant_type=client_credentials&scope=SCOPE_NAME&client_id=CLIENT_ID&client_secret=CLIENT_SECRET" https://api.beta.yaas.io/hybris/oauth2/v1/token
Parameters:
- grant_type: (Required)
client_credentials
- scope: A space-separated list of scopes (URL-encoded) that your client requires to function correctly. For example, you can use the hybris.tenant={tenantName} scope for multi-tenant clients, whether services or Builder modules. If you do not provide or pass the scope as hybris.no_tenant, the services uses the identifier of the parent tenant of the client. The hybris.org parameter is not supported.
- hybris-session-id: This is a session identifier. It is generated if it is not passed.
- client_id: Provide the client ID value from the client authorization data.
- client_secret: Provide the client secret from the client authorization data.
The client ID and client secret can be passed as parameters or a Basic Authorization header (Authorization: Basic base64(client_id:client_secret)). Use the header for better security. You can find the client ID and secret in the Builder.
For more information, see the OAuth 2.0 framework.
Resource owner password credentials grant
In this flow, the resource owner gives the client access to its credentials. When making the request, the authorization server authenticates the client and validates the credentials. The flow exchanges the credentials for an access token directly.
Retrieve the client_id and client_secret parameters as described in the Client Credentials Grant flow.
Send the following request with the parameter grant_type set to password
and obtain the access token:
Example
curl -X POST 'https://api.beta.yaas.io/hybris/oauth2/v1/token' -d 'grant_type=password&hybris_id_provider=yaas&username=USERNAME&password=USER_PASSWORD&scope=SCOPE_NAME' -H 'content-type: application/x-www-form-urlencoded'
Request
curl -X POST 'https://api.beta.yaas.io/hybris/oauth2/v1/token' -d 'grant_type=password&hybris_id_provider=yaas&username=joe@sap.com&password=HisSecret123&scope=hybris.product_create' -H 'content-type: application/x-www-form-urlencoded'
Parameters:
- grant_type: (Required)
password
- hybris-session-id: This is a session identifier. It is generated if it is not passed.
- scope: A space-separated list of scopes (URL-encoded) that your client requires to function correctly. For example, you can use the hybris.tenant={tenantName} scope in multi-tenant scenarios. If you do not provide or pass it as hybris.no_tenant, the service sets it to the ID of the parent tenant of the client. Providing hybris.org with hybris.no_tenant or hybris.tenant at the same time is not allowed.
- username: (Required) The resource owner provides this value.
- password: (Required) The resource owner provides this value.
- hybris_id_provider: This is the identity provider registered in YaaS. The only supported identity provider for this flow is
yaas
.
If you don't specify the value of this parameter, the service uses the default identity provider, which issap
.
When you use the Resource Owner Password Credentials Grant, remember to set the value of this parameter toyaas
.
You can pass the Client ID and Client Secret in the Basic Authorization header (Authorization: Basic base64(client_id:client_secret)) for increased security.
Response
A successful response returns the status code of 200
with the access token included in the body:
The Hybris-specific header hybris-user is encoded in the access token.
The table shows how the parameters client_id and client_secret influence the authorization results:
client_id is provided | client_secret is provided | client is passed in token | client is trusted |
---|---|---|---|
No | No | No | No |
Yes | No | Yes | No |
Yes | Yes | Yes | Yes |
For more information, see the OAuth 2.0 framework.
Basic Authorization Header
Use the Authorization header to pass your client_id and client_secret (Base64-encoded) in requests for the access token. This is recommended for security reasons.
Example
- Method: POST
- Request URL:
/token
curl -X POST -H "Authorization: Basic (base64($clientId:$clientSecret))" -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=client_credentials' 'https://api.beta.yaas.io/hybris/oauth2/v1/token'
Request
curl -X POST -H "Authorization: Basic ZTURcmntdnluG7FLbGZIRGZGT5hsUjhOdPOqRnZhtG06elBXZlJxWU1PPjdyL2EwUU==" -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=client_credentials' 'https://api.beta.yaas.io/hybris/oauth2/v1/token'
Response
- Status code:
200
- Body:
{
"token_type":"Bearer",
"access_token":"001-f9a0e5af-56da-4bae-a100-39848d714605",
"expires_in":3600,
"scope":"hybris.tenant=$tenant"
}
Authentication Attempts Limit
Brute-force attacks try commonly-used passwords, or combinations of letters and numbers, to access protected resources. The attackers analyze the server responses until they succeed.
This diagram shows the sequence of such an attempt when you log in to the Builder:
In order to prevent such attacks, the maximum number of invalid authentication attempts in YaaS is limited to 15 within the defined interval of 15 minutes. Each unsuccessful attempt restarts this time interval. An account goes into the blocked status when this value is reached, and the service returns a code 400
bad request error with the message Too many unsuccessful authentication attempts. Try again later.
The account is automatically released when the blocking period expires. Currently, it's 15 minutes. The invalid login attempts during the account lock do not extend the blocking period.
Scopes and Subscriptions
Our mission in YaaS is to provide you with the environment where services interact in a secure way.
When you create a service, you can protect it with scopes. Scopes are the permission settings that govern the access to the service's resources and HTTP methods used to access them. When you request for an access token, the OAuth2 service verifies the requested scopes against the subscriptions and user roles of the requesting party.
If you want a service to act in the name of your project, you need to subscribe to a package that includes this service. The range of actions that a service you subscribe can take in the name of your project is secured by scopes.
Example
Monica is the owner of a successful project named luckyshoe. Her project subscribes to the SAP Hybris Order Management package that includes the Order service which allows you to manage orders.
Developers from a different project create a service named the Blue Service. It offers special loyalty coupons for customers. The Blue Service service has a client that can communicate with the services from the Order Management package.
Monica really likes the functionality offered by the Blue Service and decides to implement it in her own project. YaaS secures project data separation and Monica knows that other subscribers of the Order Management package cannot read luckyshoe's customers' orders.
The YaaS OAuth2 service issues access tokens that allow to access the resources of the luckyshoe project only to the services that Monica allows to act on behalf of her project. To allow a service to act on behalf of a project, the project must subscribe to that service.
What does Monica need to do to take advantage of the functionality offered by the Blue Service?
She must subscribe to the Ribbons package that includes the Blue Service. When Monica subscribes to the Ribbons package, she allows the services that are included in this package to act on behalf of her project.
As a result, the Blue Service, which is a part of the package that Monica subscribes, can read the order data of the luckyshoe project's customers. The hybris.tenant=luckyshoe scope must be sent in requests for the access token.
The Jealous Service cannot get the luckyshoe project data from the Order service. Monica does not subscribe to the Sandals package, and as a result the Jealous Service's client can't obtain an access token with the hybris.tenant=luckyshoe scope.
This diagram shows how subscriptions influence the scopes granted in the access token:
For more information about scopes, see the Scopes document. To find out more about the packages you can subscribe to in YaaS, visit the YaaS Market.
Single Sign-On
When you request for an access token, you can also get an OpenID Connect 1.0 id_token. You can get the id_token in the Implicit Grant flow and in the Authorization Code Grant flow.
In the Authorization Code Grant flow, you can get an id_token by including the openid
scope in the request for the authorization code. The service returns the id_token in the response body, after the client successfully exhanges the authorization code for an access token.
For more information, see the Grants section of the documentation.
In the Implicit Grant flow, the client can request for an id_token by setting the request parameter response_type
to id_token token
. When the user is successfully authenticated, the service returns the id_token in the Location header of the response.
By using the id_token in subsequent requests for access tokens, the client can acquire a new access token for a different tenant without interrupting the user experience with login prompts.
The client passes the id_token hint (id_token_hint
) as:
- A form parameter for POST requests
- A query parameter for GET requests
The client must store the id_token securely so that the user's identity remains confidential. For more information, see the OpenID Connect 1.0 specification.
The following example shows a single sign-on flow.
Acquire an access token with id_token. Note the use of the
id_token token
andnonce
parameters, which are required by the OpenID Connect specification. The correct response contains both the access token and an id_token. The id_token can be used in subsequent requests to the/authorize
endpoint. This shows a typical request:curl -i -H "Content-Type: application/x-www-form-urlencoded" -X POST -d "response_type=id_token token&client_id=CLIENT_ID&nonce=NONCE&scope=SCOPE&state=STATE" https://api.beta.yaas.io/hybris/oauth2/v1/authorize
Use the id_token acquired in the first step to get an access token for another tenant. The response from the service is the same as in the first step. However, this time the service accepts the id_token provided as the value of the
id_token_hint
parameter. The user doesn't have to provide credentials on a sign-in screen to continue. This shows a typical request:curl -i -H "Content-Type: application/x-www-form-urlencoded" -X POST -d "response_type=token&client_id=CLIENT_ID&scope=SCOPE&state=STATE&id_token_hint=ID_TOKEN_OBTAINED_IN_CALL_FROM_STEP_1" https://api.beta.yaas.io/hybris/oauth2/v1/authorize
Validate an ID token
JWT - JSON Web Token
JSON Web Token (JWT) represents security claims that can be shared between parties without the need to store them. Find more information in the JSON Web Token (JWT) Profile documentation.A JWT Access Token is based on the following format: HEADER.PAYLOAD.SIGNATURE
- The HEADER includes two values:
{ "typ": "JWT", "alg":"RS256" }
The authorization server in YaaS uses the RS256 signing algorithm. - The PAYLOAD is a Base64 URL-safe encoding of a JSON object with requested claims. For example:
This shows the decoded payload of a token:Value Description iss (issuer) This is the identifier of the OpenID Provider (case-sensitive URL, using the HTTPS protocol). aud (audience) This represents the party that the id token
is issued for. It must contain the client id.exp (expiration) This is a deadline after which the id token
cannot be processed. The value is ajson
number of seconds from 1970-01-01t00:00:00z as measured in UTC until the date/time.nonce (nonce) This is a string value used to correlate the client session with an id token
and mitigate replay attacks.{ "email": "radean.zacierik@ssp.com", "nonce": "nonce123", "iat": 1444818815, "exp": 1446292434484, "aud": "heYyzed4RkIEQGmvcD067xzAYHVWROzm2D", "iss": "<a href="https://api.stage.yaas.io/hybris/authentication/v1">https://api.stage.yaas.io/hybris/authentication/v1</a>", "sub": "radean.zacierik@ssp.com" }
- The SIGNATURE is made up of the hashed HEADER, PAYLOAD, and SECRET, which is the signature of the server.
This shows an example of a JSON Web Token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJlbWFpbCI6InJhZGVhbi56YWNpZXJpa0Bzc3AuY29tIiwibm9uY2UiOiJub25jZTEyMyIsInNjb3BlIjpbInNjb3BlMSIsImh5YnJpcy5vcmc9dGVzdGVyb3MiXSwiaWF0IjoxNDQ0ODE4ODE1LCJleHAiOjE0NDYyOTI0MzQ0ODQsImF1ZCI6ImhlWXl6ZWQ0UmtJRVFHbXZjRDA2N3h6QVlIVldST3ptMkQiLCJpc3MiOiJodHRwczovL2FwaS5zdGFnZS55YWFzLmlvL2h5YnJpcy9hdXRoZW50aWNhdGlvbi9iMSIsInN1YiI6InJhZGVhbi56YWNpZXJpa0Bzc3AuY29tIn0.X5yBDQmOagKPU6cZuhuVWtHInWNrW9Qhg1rnx4uU6iaZSiA1lNFgPVlU8eycI0xl86azQK1d6Gno-x-4ElOO1DXUan9ox1UhNHuu4Sq-e80C9RfLRC2vQ9jOyd4GkyGS5bcNK55GL50vnm7PSerjGi06O8HTwvMlnv88njmg2Bc
ID token validation
ID tokens should be validated, as they are sensitive and can be intercepted and abused.JWT Access Tokens use the asymmetric cryptography to establish their validity. The OAuth 2.0 Server signs the token with a private key and the requesting party can verify the token using the server’s public key.
You should validate whether the content of your ID token (JWT) is properly signed with the appropriate authorization server public key from YaaS:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzvTWJNAjx9bSmGmcPaVw
s1rl65tgXE5fGNucsFdUy/y42EZpW48FrqWwgYs33S/AkTxITtZWh82EW9YMXLBY
8l3LFi4GGOTRpV1/5+PjCUehNS/LY026GhrmAxNkJip60ZyWQdLLrz7IQownKT+L
PPr+IrMgousx62trrWQfjimgSIKXnC4Zcp64bv0zdcrc/HXPc9C7PNj/xzSC08/3
Gw4dBgtswYN7NuR8EArd92UkZzsWfXYdvvN1RSyqc/FpKFAEaFDxileRL6TbBGe7
A7J1RuEQalp6q5378uzTsiTQb0o+9952SoL2W5l63jrLG9THD1oF4v+Xb4Afb0tK
EwIDAQAB
-----END PUBLIC KEY-----
Additionally, make sure:
- The iss value is set to
https://api.beta.yaas.io/hybris/authorization/v1
on production or tohttps://api.stage.yaas.io/hybris/authorization/v1
on the stage environment. - The aud value contains the client ID of your client. Currently, YaaS does not support multiple audiences.
- The exp value of the ID token is not expired. Allow some margin to account for potential time differences between parties.
Use the values from the ID token payload to extend and customize your validation, as applicable.
Request Headers
To learn what Hybris-specific headers the API Proxy sets on request to upstream services, read the API Proxy documentation here.
URL Rewrite
Introduction
The API proxy provides the URL Rewrite mechanism that is essential to services that use self-containing links. When a service generates paged responses with link
headers, they encode access to the previous and the next response pages. In YaaS, no external client should be able to access the service directly, using its internal address. The only way to access the service is to use the public API proxy URL, called Generated Proxy URL in the Builder. The problem is that the service only knows its "internal" URL, which is the URL it is deployed to (or the deployment IP address only).
Case
How can a service make use of the generated self-containing link, if it doesn't know its Generated Proxy URL (public API proxy URL)?
Solution
The API proxy offers the URL Rewrite mechanism to make it easier for service providers to handle such use cases. If the service wants to generate links that refer to itself, it should use its private deployment URL, regardless of its public API proxy URL. When the API proxy processes the response from the service, it transparently rewrites the necessary URL parts and changes the service private deployment URL to its Generated Proxy URL. The proxy only rewrites URLs that match the Source URL of the service, as configured in the Builder. During the rewrite, additional URL components beyond Source URL, such as additional path segments, query, and fragment components (if any) are preserved. The URL Rewrite mechanism scans the entire response body for these content types:
- application/json
- text/plain
- text/html
and two headers: - link
- location
This shows the process flow:
Example
This example shows the result of the API proxy rewrite processing.
Service definition:
- Identifier of a service:
torch
- Source URL: http://torch-v1.hunt.io
- Generated Proxy URL: https://api.beta.yaas.io/hybris/torch/v1
When a GET request is sent to https://api.beta.yaas.io/hybris/torch/v1/fire/path?flame=a&burn=b
, assume the service responds with a body containing the following JSON payload:
{
"seeAlso":"http://torch-v1.hunt.io/new/path?myName=Classified",
"additionalInfo": "https://www.rfc-editor.org/rfc/rfc20.txt"
}
The API proxy processes the response and substitutes the matching URL with:
{
"seeAlso":"https://api.beta.yaas.io/hybris/torch/v1/new/path?myName=Classified",
"additionalInfo": "https://www.rfc-editor.org/rfc/rfc20.txt"
}
Result
http://torch-v1.hunt.io
(source URL) is replaced with https://api.beta.yaas.io/hybris/torch/v1
(Generated Proxy URL).
Notice that:
- the protocols of the source and proxy URLs are different
- additional path and query components are preserved ("/new/path?myName=Classified")
- the second link ("additionalInfo") is NOT rewritten, since it doesn't match the service's Source URL
Introduction to Tutorials
Tutorials are designed so that you can check the API Console, use the cURL commands, and interactively learn the API. Follow the interactive tutorial and see the real-life responses from the OAuth2 service.
Interactive - Get An Access Token
In this tutorial, get an access token with the proper scope and use it to interact with a service in YaaS. You can:
- Use the credentials of a client generated in the Quick Setup section to acquire your own access token, with the Client Credentials Grant flow.
- Add a product to the project.
- Change the required scopes in the request for the access token.
- Retrieve the list of products.
You need to pass the scopes that are defined for the Product service that is a part of the Product Content package. For more information about this package, see the YaaS Market.
1. Get all your variables in one place
These are the variables used in the tutorial:
clientId = {{clientId}};
clientSecret = {{clientSecret}};
tenant = {{projectId}};
client = {{clientName}};
scopesRequired = 'hybris.tenant='+tenant+' hybris.product_create';
These are the required scopes:
- hybris.tenant - This reflects the project.
- hybris.product_create - This is required to add a product in a project.
2. Get an access token
Create an API client for the OAuth2 service:
API.createClient('oAuth2Service',
'/services/oauth2/v1/api.raml');
Now retrieve the access token:
AccessToken = oAuth2Service.token.post({
'client_id' : clientId,
'client_secret': clientSecret,
'grant_type' : 'client_credentials',
'token_type': 'Bearer',
'scope': scopesRequired
});
When the access token is successfully issued, the service returns the code 200
. Expand the response body and verify if the scope includes hybris.product_create.
Make the calls simpler and the code cleaner by assigning the access token to a variable:
access_token = AccessToken.body.access_token;
3. Add a product to your project
Create an API client for the Product service:
API.createClient('productService',
'/services/product/v2/api.raml');
Create a product. The parameter code must be unique in a given project.
prod_obj = productService.tenant(tenant).products.post({
'name': 'My awesome design',
'code': 'SampleCode123',
'description': 'The best design, no doubt.'
},
{
headers: {
'Authorization': 'Bearer ' + access_token,
'Content-Language': 'en',
'Content-type' : 'application/json'
}
})
When the product is successfully added to your project, the service returns a 201
status code. The scope hybris.product_create in your access token allows you to perform this action.
Expand the response body to reveal the product details.
4. Retrieve products in a project
You need the scope hybris.product_read_unpublished to list inactive products in your project. The token obtained in the first step of this tutorial does not include it. Add the required scope in the request for the access token:
AccessToken = oAuth2Service.token.post({
'client_id' : clientId,
'client_secret': clientSecret,
'grant_type' : 'client_credentials',
'token_type': 'Bearer',
'scope': 'hybris.tenant='+tenant+' hybris.product_read_unpublished'
});
This lists the required scopes:
- hybris.tenant - This reflects the project.
- hybris.product_read_unpublished - This is required to retrieve non-public products.
When the access token is successfully issued, the service returns a 200
status code. Expand the response body and verify if the scope includes hybris.product_read_unpublished.
Assign the access token to a variable:
access_token_step_4 = AccessToken.body.access_token;
Send the request to the Product service:
result = productService.tenant(tenant).products.get(null,{
headers: {
'Authorization': 'Bearer ' + access_token_step_4,
}
}
)
The service returns a 200
status code. The scope hybris.product_read_unpublished allows you to you perform this action.
Extract the response body to reveal the product details, including its ID:
productObj = result.body[0];
For more information about error codes, see the API Reference.
Get an Access Token
Interactions with services in YaaS require the authorization grant and appropriate permissions. Use these endpoints to get an access token:
token
for the Client Credentials Grant and the Resource Owner Password Credentials Grantauthorize
for the Implicit Grant
Find out how in the YaaS Bites section of the Getting Started.
For more information about error codes, see the API Reference.
Set Up the Implicit Grant Flow
Some clients, such as JavaScript applications, cannot keep credentials secret in the code. Use the OAuth 2.0 Implicit Grant flow to retrieve an access token as the result of the authorization request. For confidential clients, use the Client Credentials Grant flow from the Interactive - Get an Access Token tutorial.
Get an access token and list products in your project
This example shows how to obtain an access token and list the published products in a project. Use an existing project that has active products, or add a new one. Find out how in the Create Projects tutorial.
- For the code sample to work properly, add a client in your project and set
http://127.0.0.1:8080/
as the Redirect URI. - In the Builder, go to Projects > {My Project} > Clients > {My Client}, and use the SHOW button to reveal and retrieve the Client ID.
- Retrieve the Client ID from the Builder. Go to Projects > {My Project} > Clients > {My Client}, and use the SHOW button to reveal the Client ID.
- Make an
HTTP POST
request tohttps://api.beta.yaas.io/hybris/oauth2/v1
and the/authorize
endpoint:- In the body of the request, use the client_id and response_type parameters:
- client_id – ID of the client in your project
- response_type –
token
orid_token token
- In a JavaScript application, use the code as shown in the example:
function login() { var address = "https://api.beta.yaas.io/hybris/oauth2/v1/"; var endpoint = "authorize"; var response_type = "token"; var client_id = "YOUR_CLIENT_ID"; window.open(address + endpoint + "?" + "response_type=" + response_type + "&client_id=" + client_id); }
- In the body of the request, use the client_id and response_type parameters:
- After authorization, you are redirected to
http://127.0.0.1:8080/#access_token=022-e83ab3d6-ce58-46a3-9845-2e2022dacc4c&token_type=bearer&expires_in=3600
. - Extract the access token and use it in the
HTTP
request to the Product service. Use the PROJECT_ID from the Builder. Go to Projects > {My Project} > Administration. The Project ID is in the Identifier field.curl -i -H "Authorization: Bearer ACCESS_TOKEN" https://api.beta.yaas.io/hybris/product/v2/PROJECT_ID/products
- The successful response returns the code of
200 OK
and includes JSON with the product details.
Download a code example
Visit the GitHub repository and download the tutorial which contains a code sample. Find out how to use it in the README.md file.
For more information about error codes, see the API Reference.
Retrieve User Information
Introduction
YaaS provides an OpenID Connect 1.0 compatible endpoint to obtain claims about the authenticated end user.
The userinfo
endpoint
The userinfo
endpoint is an OAuth 2.0 protected resource that returns claims about the authenticated user. The claims are determined based on the information decoded from the access token.
Request:
To retrieve the user specific information you need:
- Method: GET or POST
- Request URL:
https://api.beta.yaas.io/hybris/oauth2/v1/userinfo
- Headers:
- Authorization - This includes a valid OAuth2 access token issued for a user.
Example
Send a request using the GET or POST method with a Bearer access token set in the Authorization header:
curl -H "Authorization: Bearer someAccessToken" -X GET https://api.beta.yaas.io/hybris/oauth2/v1/userinfo
or
curl -H "Authorization: Bearer someAccessToken" -X POST https://api.beta.yaas.io/hybris/oauth2/v1/userinfo
Example
The following is an example of how to retrieve the user info encoded in the access token:
curl -H "Authorization: Bearer 019-98433a7b-58e3-42b5-a9c4-rff95d3a9f14" -X GET https://api.beta.yaas.io/hybris/oauth2/v1/userinfo
Response
The successful response returns a 200
status code. An example JSON content in the response body looks similar to the following:
{
"sub": "userEmail"
}
The response contains a standard claim "sub" that contains a user email address.
Response
If an access token is not valid or does not contain information about the user, such as if the access token was issued on behalf of the service itself and is not associated with the user, the endpoint returns an unauthorized response with an error 401
status code and description set in the WWW-Authenticate header:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token", error_description="Invalid or expired access token."
For more information about error codes, see the API Reference.
Retrieve Token Information
The tokeninfo
endpoint allows you to retrieve information encoded in the access token:
- scopes, including the tenant (project) that the caller is acting upon
- the ID of the client that authorizes the request
- the identifier of the client's parent project.
With the query parameter details set to true, the service returns the list of services that the client parent project subscribes. Match the scopes in the access token with the service scopes and check if the permissions attached to your client are sufficient to access the service resources.
Request:
To retrieve the information encoded in the specific access token you need:
- Method: GET
- Request URL:
https://api.beta.yaas.io/hybris/oauth2/v1/tokeninfo
- Query parameters:
- access_token - This parameter is required and sends the token you want to evaluate.
- details - This parameter is optional and it is set to false by default. If it is set to true, the server response contains additional information, such as the list of allowed services.
Example
Send a request using the GET method with the access token and the query parameter details set to false:
curl -X GET https://api.beta.yaas.io/hybris/oauth2/v1/tokeninfo?access_token=022-fea23c05-04f9-42f7-9762-60eb407dcab4&details=false
Response
The successful response returns a 200
status code. An example JSON content in the response body looks similar to the following:
{
"scopes": [
"hybris.tenant=photoworks"
],
"tenant": "photoworks",
"clientId": "YkkJCHNYggYnmkrJY0L1QTbhHOJahsjR"
}
If your access token is issued for a user, the response includes additional value:
{
"scopes": [
"hybris.tenant=photoworks"
],
"tenant": "photoworks",
"clientId": "YkkJCHNYggYnmkrJY0L1QTbhHOJahsjR",
"user": "user@user.com"
}
Example
Send a request using the GET method with the access token and the query parameter details set to true:
curl -X GET https://api.beta.yaas.io/hybris/oauth2/v1/tokeninfo?access_token=022-fea23c05-04f9-42f7-9762-60eb407dcab4&details=true
Response
The successful response returns a 200
status code. An example JSON content in the response body looks similar to the following:
{
"scopes": [
"hybris.product_create",
"hybris.tenant=photoworks"
],
"tenant": "photoworks",
"clientId": "YkkJCHNYggYnmkrJY0L1QTbhHOJahsjR"
"allowedServices": [
{
"name": "product",
"proxyUrl": [
"https://api.beta.yaas.io/hybris/product/v2",
"https://api.us.yaas.io/hybris/product/v2",
"https://api.beta.yaas.io/hybris/product/v2"
],
"serviceScopes": [
"hybris.product_publish",
"hybris.product_delete_all",
"hybris.product_update",
"hybris.product_read_unpublished",
"hybris.product_unpublish",
"hybris.product_create",
"hybris.product_delete"
]
},
...
{
"name": "productdetails",
"proxyUrl": [
"https://api.beta.yaas.io/hybris/productdetails/v1",
"https://api.us.yaas.io/hybris/productdetails/v1",
"https://api.beta.yaas.io/hybris/productdetails/v1"
],
"serviceScopes": []
}
]
}
Note that the list of allowed services excludes those that do not require subscription: the Essential Services and services that belong to the tenant.
In this example, the client can access the Product service resources secured with the hybris.product_create scope. This is the only scope encoded in the access token that matches this service scopes.
If an access token is not valid or expired, the endpoint returns an error 400
status code:
{
"error":"invalid_query_parameter",
"error_description":"access_token is invalid",
"error_uri":"https://api.yaas.io/patterns/errortypes.html"
}
For more information about error codes, see the API Reference.
Use caseYou are the shop manager and you try to add a product in your project. The request fails and you receive an error 403
status code and type insufficient_permissions
.
Solution
If you want to add a product in your project, the project needs to subscribe to the Product Content package. The Product service is a part of this package. The API Reference reads that the /{tenant}/product
endpoint requires the hybris.product_create
scope for the POST method, and the URI parameter tenant must match the value of the hybris.tenant scope in the acesss token.
Use the tokeninfo
endpoint and find out what permission settings are missing. Check these values in the access token:
- The list of the allowed services must include the Product service. If it doesn't, this means that your tenant does not subscribe the Product Content package, or the subsciption expired. For more information, see the YaaS Market.
- The list of scopes must include hybris.product_create. If it doesn't, this means that the calling client did not include this scope in the request for an access token. For more information, see the Getting Started Guides.
- The hybris.tenant scope must match the value of the URI parameter in the call to the
/{tenant}/products
endpoint. For more information how to request an access token for a tenant, see the Clients document.
Glossary
Term | Description |
---|---|
account | User"s identity represented by email address, which is the account identifier, and a password. |
client | An OAuth2 client as defined in the OAuth 2.0 Authorization Framework. It is created within a project and can interact with services in YaaS. |
project | Company"s planned piece of work. It is required for registering clients and managing their credentials, and package subscriptions. It includes Staff members who have different User roles assigned. |
scopes | The access rights to resources and operations in the service, such as hybris.product_manage, which enables you to create and modify products. |
service | Software running as a part of a hosted application on a server. |
staff members | A group of developers that develop and work with a project. |
subscription | A contract granting a user the right to use an API product in a project. |
user role | Set of permissions defined in the project. There are two default roles: OWNER and VIEWER. |
If you find any information that is unclear or incorrect, please let us know so that we can improve the Dev Portal content.
Use our private help channel. Receive updates over email and contact our specialists directly.
If you need more information about this topic, visit hybris Experts to post your own question and interact with our community and experts.