Cloudentity provides OAuth and OIDC management directly integrated into the platform. OAuth and OIDC security is directly tied to security policies manged in the TrUST Engine, providing secirty to Users, Services and Things at the edge and in the core data center.
OAuth2.0
OAuth 2.0 is the industry-standard protocol for authorization. OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.
Cloudentity provides an implementation of OAuth 2.0 specification to enable application authorization backed by Cloudentity Identity Managment Apis and Cloudentity Authorization trust engine capabilities.
OAuth2.0 Terminology
OAuth2.0 specifications uses following terms and its important to understand these terms while talking about the actors, roles, specifications and functionality.
Resource owner |
The user who authorizes an application to access their account. The application’s access to the user’s account is limited to the “scope” of the authorization granted |
Resource server |
A server which sits in front of protected resources |
Authorization server |
A server which issues access tokens after successfully authenticating a client and resource owner, and authorizing the request |
Client |
An application which accesses protected resources on behalf of the resource owner |
Grant |
A grant is a method of acquiring an access token. |
Scope |
represents a permission to access a resource |
Authorization code |
An intermediary token generated when a user authorizes a client to access protected resources on their behalf |
Access Token |
A token used to access protected resources. |
Refresh Token |
A long lived token used to exchange for access token |
Client Registration
Oauth 2.0 and OpenID Connect requires client applications to have an existing registration with the Oauth2.0/OpenID Connect server before requests will be processed by the server. Before initiating the protocol, the client must register with the authorization server. The means through which the client registers is not part of the OAuth2.0 specification and is left to the implementation support of the server itself.
When client registration is supported by the authorization server, registration can rely on other means for establishing trust and obtaining the required client properties.
Cloudentity OAuth2.0 server supports following client registration process * Static Client Registration Process * Dynamic Client Registration
Static Client registration
Cloudentity has the concept of applications. OAuth2.0 clients are treated as applications of specific type "OAuth Client". OAuth 2.0 Client registrations can be done using Cloudentity application service API’s. To access Cloudentity application services, a caller should have sufficient access rights.
Using Cloudentity API
TODO: Put a link to application service, client registration api’s. And then add some API examples for that on how to register an Oauth 2.0 client
Using Cloudentity Administrative UI
Register an OAuth Client
Log in with your Cloudentity account and navigate to your user profile (self-service) page. In the upper-right-hand navigation menu, select "Developer." If you do not see this link, contact your Cloudentity admin to have the the developer privilege granted to your account.
Click the "Create" button. Give your application a name and description.
Click "Create" to continue. You will see a list of options to tailor your OAuth client configuration to the type of app you are developing. Choose the option that best fits your client application.
Your OAuth app is created! A client ID and secret are automatically generated. Copy these values and put them in the appropriate place in your client app configuration. (For services deployed in a Kubernetes cluster, this may be in an environment file like "env.yaml.")
Pay close attention to the fields below the client credentials and authorization server. They may need to be modified to fit your use case. If you are wiring this to a JS frontend, for example, make sure that the redirect URL matches that of the webapp URL (and port, if you are serving the app locally in dev mode). Otherwise, the OAuth app will not issue an access token at login and will display an error.
To add multiple redirect URLs, comma separate them. (for example, you are serving the client app locally for development, then testing it from a Kubernetes cluster, using the same OAuth app).
Also, make sure to choose the correct grant type or types (multiple selection is possible). "Implicit" and "Client Credentials" are common choices.
Dynamic Client registration
Partially supported in Cloudentity stack and fully functional dynamic client registration specification will be soon supported in the stack.
Resource Server
Resource server is a server or a service that accepts and responds to protected resource requests.
In OAuth2.0 terminology, resource servers are intended to serve protected resources, if
the incoming request has a proper access token issued by a compliant OAuth Authorization Server
.
Exposing your business/domain API(s)
-
Business/domain API services will be the Resource Servers
-
Cloudentity OIDC stack will be the Authorization Server
Exposing Cloudentity Identity API(s)
-
Cloudentity API services will be the Resource Servers
-
Cloudentity OIDC stack will be the Authorization Server
Verify Access Tokens
Resource server must serve the requested resource only after evaluating the authenticity, context
and authorization proof presented as part of incoming request.
Applications must request resources with HTTP Authorization header containing an access token, obtained
from a compliant OAuth Authorization Server
supported by the Resource Server
in below format:
Authorization: Bearer <put-your-access-token-issued-by-authorization-server>
The evaluation function must comprise of following checks:
-
Is access token valid and issued by a known "OAuth Authorization Server"?
-
Does incoming access token have enough privilege to requested resource?
These access authorization and verification checks can be either directly built into Resource Server capability itself or can be programmed as a plugin or as an interception function/component available in front of Resource Server.
Most Resource Servers
commonly used one of the access authorization techniques:
-
Token Introspection
-
Stateless JWT
Token Introspection
Token Introspection is the recommended approach for an organization with lot of API resource servers. A central authorization server that issued the accessToken will expose the introspection endpoint to be utilized by all these API resource servers. Token introspection will return all the required details including scopes, permissions or finer grained details depending on the configuration of the system.
Token introspection capability can be built into your resource server using various techniques.
-
Cloudentity Micro-Perimeter
-
Suited for container based API resource servers
-
Can intercept all traffic onto the API server and enforce policy based access control using details around access token, user , device, things etc
-
Centralized security policy management/view available
-
Access policy updates or changes in enforcement does not require re-deployment of services
-
-
Cloudentity Micro API Gateway
-
Suited for traditional standalone deployments of API resource servers
-
Acts as a centralized reverse proxy intercepting all API traffic
-
Cloudentity authorization plugins available to policy based access control using details around access token, user , device, things etc
-
Centralized security policy management/view available
-
Access policy updates or changes in enforcement does not require re-deployment of services
-
-
Cloudentity SDK
-
Can be added as a third party library dependency
-
-
Programmatic API call within Resource Server
-
Needs to be added to each and every API resource service
-
Code duplication and prone to code refactoring
-
No centralized security policy management/view available
-
Updates or changes in enforcement might require re-deployment of services
-
Stateless JWT Inspection
OAuth specification does not specify the contents within the accessToken. So In certain scenarios, API authorization access scopes can be embedded within the accessToken issued by the authorization server itself, as a stateless JWT token. This might be good approach for organizations with less number of API resource servers to manage. This stateless approach will mostly hit a roadblock either with
-
size of authorization header
-
complexity of scope management as number of API services increased
Stateless JWT based capability can be built into your resource server using various techniques.
-
Cloudentity API GW
-
Suited for traditional standalone deployments of API resource servers
-
Acts as a centralized reverse proxy intercepting all API traffic
-
Cloudentity JWT authorization plugin to evaluate policy based access control using incoming JWT token details
-
Centralized security policy management/view available
-
Access policy pdates or changes in enforcement does not require re-deployment of services
-
-
Cloudentity micro-perimeter
-
Suited for container based API resource servers
-
Can intercept all traffic onto the API server and enforce policy based access control using incoming JWT token details
-
Centralized security policy management/view available
-
Access policy pdates or changes in enforcement does not require re-deployment of services
-
-
Cloudentity SDK
-
Can be added as a third party library dependency
-
-
Programmatic enforcement within Resource Server
-
Needs to be added to each and every API resource service
-
Code duplication and prone to code refactoring
-
No centralized security policy management/view available
-
Updates or changes in enforcement might require re-deployment of services
-
Grants
The OAuth 2.0 framework specifies following grant types for various use cases. These are mainly used to fetch accessToken from an OAuth Authorization Server.
-
Authorization Code
-
Client Credentials
-
Implicit
-
Resource Owner Password Credentials
Authorization Code
Tip
|
When it should be used? It should be used as soon as the client is a web server. It allows you to obtain a long-lived access token since it can be renewed with a refresh token (if the authorization server enables it). |
Obtain authorization code
GET https://cloudentity.local.cloudentity.com/oauth/authorize?response_type=code&client_id=4aeabda1-5b8b-462f-8bca-2b78183e2342&state=&redirect_uri=http://localhost:1234 http://localhost:1234/?code=s7L4Zb&state=
Exchange code for accessToken
POST Authorization: Basic <client_id as username, client_credentials as password> Content-Type: application/x-www-form-urlencoded
POST Body: grant_type=authorization_code&code=s7L4Zb&redirect_uri=http://localhost:1234 https://cloudentity.local.cloudentity.com/oauth/token
{ "access_token": "eyJraWQiOiJvaWRjIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIyYWI5ZjAyYy1hYTQ2LTQ4ZDctYTUxOS1jY2RhYTVlOWUwY2MiLCJzY29wZSI6ImFkZHJlc3MgcGhvbmUgb3BlbmlkIGVtYWlsIHByb2ZpbGUgb2ZmbGluZV9hY2Nlc3MiLCJpc3MiOiJodHRwczpcL1wvY2xvdWRlbnRpdHkubG9jYWwuY2xvdWRlbnRpdHkuY29tXC9vYXV0aFwvIiwiZXhwIjoxNTI3MTg4MjEwLCJpYXQiOjE1MjcxODQ2MTAsImp0aSI6ImMxODBiM2ZlLTZjZDUtNGZiZC1iYzQ4LTFiNjRlOGUwZWM1MyJ9.gh2eVA7sw8DslbzdL7407Z5GQSoqaBUZuNE1_gUw5abWqzhmm0BkcykpLdWwIdkPZONDLJ4ozaVVJ7RbEV1zAY7Q_eLhkFQVfXKNbb65jP-S6IH2yhcoS9IjUySL0EqQCZ5RTDlezNpP4-5aVIBZr2QLd4oCa5XfaTE1rUAlmg8", "token_type": "Bearer", "refresh_token": "eyJhbGciOiJub25lIn0.eyJqdGkiOiJiYjcyZjNmYS00NGQyLTQ4N2MtYWEwMC02ODNhMzg2M2QyMjkifQ.", "expires_in": 3599, "scope": "address phone openid email profile offline_access", "id_token": "eyJraWQiOiJvaWRjIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIyYWI5ZjAyYy1hYTQ2LTQ4ZDctYTUxOS1jY2RhYTVlOWUwY2MiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYWRkcmVzcyI6eyJzdHJlZXRfYWRkcmVzcyI6IjI4MTUgMm5kIEF2ZSwgU3VpdGUgMzkwIiwiY291bnRyeSI6IlVTIiwibG9jYWxpdHkiOiJTZWF0dGxlIiwicmVnaW9uIjoiV0EiLCJwb3N0YWxfY29kZSI6Ijk4MTIxIn0sImtpZCI6Im9pZGMiLCJpc3MiOiJodHRwczpcL1wvY2xvdWRlbnRpdHkubG9jYWwuY2xvdWRlbnRpdHkuY29tXC9vYXV0aFwvIiwicGhvbmVfbnVtYmVyX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbkBjbG91ZGVudGl0eS5jb20iLCJnaXZlbl9uYW1lIjoiQWRtaW4iLCJhdWQiOiI0YWVhYmRhMS01YjhiLTQ2MmYtOGJjYS0yYjc4MTgzZTIzNDIiLCJhdXRoX3RpbWUiOjE1MjcxODQzOTIsIm5hbWUiOiJBZG1pbiBDbG91ZGVudGl0eSIsInBob25lX251bWJlciI6IjE4ODg3OTY4MzQxIiwiZXhwIjoxNTI3MTg4MjEwLCJpYXQiOjE1MjcxODQ2MTAsImZhbWlseV9uYW1lIjoiQ2xvdWRlbnRpdHkiLCJqdGkiOiIxYzU0YTg5Zi04YzYzLTQzZDAtYTI2YS0zNTI2Y2Y5NzlmMWYiLCJlbWFpbCI6ImFkbWluQGNsb3VkZW50aXR5LmNvbSJ9.B3XvvY-gwf9Y_0UJJaAtldpfaL-6a1KAfmw_CQOlW7MOHohMvWeH8IMb3OlpQlGjhP_wG8oncWPSFFyaftYwY39qTzjn9xFNLNYT0VGF-wLYji9av6E5wpMK_a3CyrYt_EdM5vVCTxYI1WY5fBv5OwyP-Bt9GC5TxJFyaWxVFtM" }
Client Credentials
Tip
|
When it should be used? This type of authorization is used when the client is himself the resource owner. There is no authorization to obtain from the end-user. |
Request
POST https://cloudentity.local.cloudentity.com/oauth/token Authorization: Basic <client_id as username, client_credentials as password> Content-Type: application/x-www-form-urlencoded POST Body: grant_type=client_credentials
Response
{ "access_token": "eyJraWQiOiJvaWRjIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiI0YWVhYmRhMS01YjhiLTQ2MmYtOGJjYS0yYjc4MTgzZTIzNDIiLCJzY29wZSI6ImFkZHJlc3MgcGhvbmUgb3BlbmlkIGVtYWlsIHByb2ZpbGUgb2ZmbGluZV9hY2Nlc3MiLCJpc3MiOiJodHRwczpcL1wvY2xvdWRlbnRpdHkubG9jYWwuY2xvdWRlbnRpdHkuY29tXC9vYXV0aFwvIiwiZXhwIjoxNTI3MTg5ODM1LCJpYXQiOjE1MjcxODYyMzUsImp0aSI6ImY4NmZlNmY5LTFiMTktNGNhMS04NTU3LTliOGE0YTc1NWRkMiJ9.ReLcOWiW_EgB3G-iS9yH7ZiQKWjkg6JydqXckYHWa8MMAZxIWXmrk1mmPIQSQ0JBRBBsPqAKy8BaVW6fDb7bmnc5TXp2q9os2RrVY70gAQt3nCczxD6VhY13hwxZz2tCu9fQDAr0UDepe88DPNELkOn-Jp4t3py77aTP5xC7dbo", "token_type": "Bearer", "expires_in": 3599, "scope": "address phone openid email profile offline_access" }
Tip
|
RFC 6749 — Client Credentials Grant. https://tools.ietf.org/html/rfc6749#section-4.4 |
Implicit
Tip
|
When it should be used? It is typically used when the client is running in a browser using a scripting language such as Javascript. This grant type does not allow the issuance of a refresh token. See http://tools.ietf.org/html/rfc6749#section-4.2 for more information |
Maybe you wonder how the client can make a call to the Facebook API with Javascript without being blocked because of the Same Origin Policy? Well, this cross-domain request is possible because Cloudentity server authorizes it thanks to a header called Access-Control-Allow-Origin present in the response.
More information about Cross-Origin Resource Sharing (CORS): https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS#The_HTTP_response_headers.
Warning
|
This type of authorization should only be used if no other type of authorization is available. Indeed, it is the least secure because the access token is exposed (and therefore vulnerable) on the client side. |
GET https://cloudentity.local.cloudentity.com/oauth/authorize?response_type=token&client_id=4aeabda1-5b8b-462f-8bca-2b78183e2342&state=&redirect_uri=http://localhost:1234
Response
http://localhost:1234/#access_token=eyJraWQiOiJvaWRjIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIyYWI5ZjAyYy1hYTQ2LTQ4ZDctYTUxOS1jY2RhYTVlOWUwY2MiLCJzY29wZSI6ImFkZHJlc3MgcGhvbmUgb3BlbmlkIGVtYWlsIHByb2ZpbGUgb2ZmbGluZV9hY2Nlc3MiLCJpc3MiOiJodHRwczpcL1wvY2xvdWRlbnRpdHkubG9jYWwuY2xvdWRlbnRpdHkuY29tXC9vYXV0aFwvIiwiZXhwIjoxNTI3MTg4ODgzLCJpYXQiOjE1MjcxODUyODMsImp0aSI6IjNkMDUyZjZmLWZkOTMtNDU0Ny1hMzIxLWFkZDA3MWY2NGJiNSJ9.C0Htuy5g-myZrrOsKRVI0_Fpa7HVXBorJEPS03mKuUUHCUTxYdZ8TM1ogowunbc0JETLmasagknh3yUC2erW0Eulvbs33NpP2VvE1usgmH7gnILJ8jWCu5GTToB3CbDmzgehq1Ribk7ZIdl2t8UFhpkjxrOmj-4Np3qTFLr4MwY&token_type=Bearer&state=&expires_in=3599&scope=address%20phone%20openid%20email%20profile%20offline_access&id_token=eyJraWQiOiJvaWRjIiwiYWxnIjoiUlMyNTYifQ.eyJhdF9oYXNoIjoiQURiOGZLTlUwSDBvUTFTTGlZV051ZyIsInN1YiI6IjJhYjlmMDJjLWFhNDYtNDhkNy1hNTE5LWNjZGFhNWU5ZTBjYyIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhZGRyZXNzIjp7InN0cmVldF9hZGRyZXNzIjoiMjgxNSAybmQgQXZlLCBTdWl0ZSAzOTAiLCJjb3VudHJ5IjoiVVMiLCJsb2NhbGl0eSI6IlNlYXR0bGUiLCJyZWdpb24iOiJXQSIsInBvc3RhbF9jb2RlIjoiOTgxMjEifSwiYW1yIjpbInB3ZCJdLCJraWQiOiJvaWRjIiwiaXNzIjoiaHR0cHM6XC9cL2Nsb3VkZW50aXR5LmxvY2FsLmNsb3VkZW50aXR5LmNvbVwvb2F1dGhcLyIsInBob25lX251bWJlcl92ZXJpZmllZCI6dHJ1ZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW5AY2xvdWRlbnRpdHkuY29tIiwiZ2l2ZW5fbmFtZSI6IkFkbWluIiwiYXVkIjoiNGFlYWJkYTEtNWI4Yi00NjJmLThiY2EtMmI3ODE4M2UyMzQyIiwiYWNyIjoiMiIsImF1dGhfdGltZSI6MTUyNzE4NTI4MywibmFtZSI6IkFkbWluIENsb3VkZW50aXR5IiwicGhvbmVfbnVtYmVyIjoiMTg4ODc5NjgzNDEiLCJleHAiOjE1MjcxODg4ODMsImlhdCI6MTUyNzE4NTI4MywiZmFtaWx5X25hbWUiOiJDbG91ZGVudGl0eSIsImp0aSI6IjczNzkzMzQ3LTMyMWMtNGVkNS05YzU2LWY2NGFjMjU3ODg2MSIsImVtYWlsIjoiYWRtaW5AY2xvdWRlbnRpdHkuY29tIn0.gv4PooHy7raObfSkvmKv846bIp0qO4IyxlG_4mO2dEXM-_N0db-vkVpCUkIV8mCihaKyjf-uT5SbVZuaiJCKnEIhoQN2uV-QBhXZ49v8wo2hACiFQEyuw6jn5S-hvREQEACEcIOzgbbqEIImErtD5Vh-w0YQgadVxPVPAp-rbj8
Resource Owner Password Credentials
Tip
|
When it should be used? With this type of authorization, the credentials (and thus the password) are sent to the client and then to the authorization server. It is therefore imperative that there is absolute trust between these two entities. It is mainly used when the client has been developed by the same authority as the authorization server. For example, we could imagine a website named example.com seeking access to protected resources of its own subdomain api.example.com. The user would not be surprised to type his login/password on the site example.com since his account was created on it. |
Warning
|
This grant type cannot be self requested while registering a client application. It can only be assigned by an administrator. |
POST https://cloudentity.local.cloudentity.com/oauth/token Header: Authorization: Basic <client_id as username, client_credentials as password> Content-Type: application/x-www-form-urlencoded Body: grant_type=password username=<username> password=<password>
{ "access_token": "eyJraWQiOiJvaWRjIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiI3NjM0MTA2Zi00MTExLTQ3YWYtYjU0Yi00OWI2NzI2ZWI5NDYiLCJzY29wZSI6ImFkZHJlc3MgcGhvbmUgb3BlbmlkIGVtYWlsIHByb2ZpbGUiLCJpc3MiOiJodHRwczpcL1wvYXJtLmxvY2FsLmNsb3VkZW50aXR5LmNvbVwvb2F1dGhcLyIsImV4cCI6MTUzNjUyNTc1MCwiaWF0IjoxNTM2NTIyMTUwLCJqdGkiOiJmMTQzMmRkOC1hZmUwLTQyZDctYmFmZC0wYjY1Y2YwNGNmM2YifQ.bOzNX7G96e56kT50osrza_w8lLJCIBBVFoVTeVm86zav55U8bKg7J0gsU_IXOyB5MLf3tb2QMJl03-gtnmwZJzMlSQWeYW2Edk6IBcaowjY05qG0cCXCbJFDEDRcToG__aZJMGprSBqFQtX_A9BsAcK6YVq7fDXrbdWSGGKur7A", "token_type": "Bearer", "expires_in": 3599, "scope": "address phone openid email profile", "id_token": "eyJraWQiOiJvaWRjIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiI3NjM0MTA2Zi00MTExLTQ3YWYtYjU0Yi00OWI2NzI2ZWI5NDYiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYWRkcmVzcyI6eyJzdHJlZXRfYWRkcmVzcyI6IjI4MTUgMm5kIEF2ZSwgU3VpdGUgMzkwIiwiY291bnRyeSI6IlVTIiwibG9jYWxpdHkiOiJTZWF0dGxlIiwicmVnaW9uIjoiV0EiLCJwb3N0YWxfY29kZSI6Ijk4MTIxIn0sImtpZCI6Im9pZGMiLCJpc3MiOiJodHRwczpcL1wvYXJtLmxvY2FsLmNsb3VkZW50aXR5LmNvbVwvb2F1dGhcLyIsInBob25lX251bWJlcl92ZXJpZmllZCI6dHJ1ZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW5AYXJtLmNsb3VkZW50aXR5LmNvbSIsImdpdmVuX25hbWUiOiJBZG1pbiIsImF1ZCI6IjVhMTY5MDc3LWY5YjUtNGJmOC1iZmQ3LTMwYmJiNmUxODBiZiIsIm5hbWUiOiJBZG1pbiBBUk0iLCJwaG9uZV9udW1iZXIiOiIxODg4Nzk2ODM0MSIsImV4cCI6MTUzNjUyNTc1MCwiaWF0IjoxNTM2NTIyMTUwLCJmYW1pbHlfbmFtZSI6IkFSTSIsImp0aSI6IjcwYjhlYTQyLWFhODMtNDQ2ZS05NWJjLTI2NWMyNDI3MzBkZiIsImVtYWlsIjoiYWRtaW5AYXJtLmNsb3VkZW50aXR5LmNvbSJ9.WNYzGtSdGUWPa3PYRtcFsXg8E181On4XC_HINn7_D2QY_wS9hdjXe4GRC9zU6LvnK9knF1aH0rGeDZGRlEAsK4tVq-IiHtFmK8D62jS2JUbhKc10HK_h0nytnl5-tZUPjtmM7sha3DyGrpe0gP5KKtxGn8ZSxnWDOvP_QE9yvoY" }
Tip
|
RFC 6749 — Resource Owner Password Credentials Grant. |
Exchange Refresh Token
When an access_token expires it is required to return to the authorization server with a refresh_token to mint a new access_token.
Because refresh tokens are typically long-lasting credentials used to request additional access tokens, the refresh token is bound to the client to which it was issued.
POST Authorization: Basic <client_id as username, client_credentials as password> Content-Type: application/x-www-form-urlencoded POST Body: grant_type=refresh_token&refresh_token=eyJhbGciOiJub25lIn0.eyJqdGkiOiJiYjcyZjNmYS00NGQyLTQ4N2MtYWEwMC02ODNhMzg2M2QyMjkifQ. {serverpath}/oauth/token
Response
{ "access_token": "eyJraWQiOiJvaWRjIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIyYWI5ZjAyYy1hYTQ2LTQ4ZDctYTUxOS1jY2RhYTVlOWUwY2MiLCJzY29wZSI6ImFkZHJlc3MgcGhvbmUgb3BlbmlkIHByb2ZpbGUgb2ZmbGluZV9hY2Nlc3MgZW1haWwiLCJpc3MiOiJodHRwczpcL1wvY2xvdWRlbnRpdHkubG9jYWwuY2xvdWRlbnRpdHkuY29tXC9vYXV0aFwvIiwiZXhwIjoxNTI3MTkwNjc0LCJpYXQiOjE1MjcxODcwNzQsImp0aSI6ImRkNTk3MmVkLThjZDctNDc5Ny04ZmNiLTRjOGUzMWU0Yjk4OCJ9.PKQc3vOX3ZOPW8eRqOKU1mCVGk5Dw8VfC16Oxy7eIznVMt6yiXiBp5mCDRlMdBDBy9WyuJ_AaGM7Af8WkGfFo47hDoYC0G5HeKreB_To0tNvSPLwWnMf0rmAXlTbqAquwr7f85FY2Z-GI8tfT3DFzUscEVmz3NMS9iMpYV7H4ME", "token_type": "Bearer", "refresh_token": "eyJhbGciOiJub25lIn0.eyJqdGkiOiJiYjcyZjNmYS00NGQyLTQ4N2MtYWEwMC02ODNhMzg2M2QyMjkifQ.", "expires_in": 3599, "scope": "address phone openid profile offline_access email", "id_token": "eyJraWQiOiJvaWRjIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIyYWI5ZjAyYy1hYTQ2LTQ4ZDctYTUxOS1jY2RhYTVlOWUwY2MiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYWRkcmVzcyI6eyJzdHJlZXRfYWRkcmVzcyI6IjI4MTUgMm5kIEF2ZSwgU3VpdGUgMzkwIiwiY291bnRyeSI6IlVTIiwibG9jYWxpdHkiOiJTZWF0dGxlIiwicmVnaW9uIjoiV0EiLCJwb3N0YWxfY29kZSI6Ijk4MTIxIn0sImtpZCI6Im9pZGMiLCJpc3MiOiJodHRwczpcL1wvY2xvdWRlbnRpdHkubG9jYWwuY2xvdWRlbnRpdHkuY29tXC9vYXV0aFwvIiwicGhvbmVfbnVtYmVyX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbkBjbG91ZGVudGl0eS5jb20iLCJnaXZlbl9uYW1lIjoiQWRtaW4iLCJhdWQiOiI0YWVhYmRhMS01YjhiLTQ2MmYtOGJjYS0yYjc4MTgzZTIzNDIiLCJhdXRoX3RpbWUiOjE1MjcxODQzOTIsIm5hbWUiOiJBZG1pbiBDbG91ZGVudGl0eSIsInBob25lX251bWJlciI6IjE4ODg3OTY4MzQxIiwiZXhwIjoxNTI3MTkwNjc0LCJpYXQiOjE1MjcxODcwNzQsImZhbWlseV9uYW1lIjoiQ2xvdWRlbnRpdHkiLCJqdGkiOiIwZjg1OGIzOC1kOGJlLTQ5ODMtOWUyNy0yNTUyYTYxOTNjZDkiLCJlbWFpbCI6ImFkbWluQGNsb3VkZW50aXR5LmNvbSJ9.gbO6goBJo5A5bQv3ZrwpU-ZUm1RqeldqTAcdpbXvJLHenr9NTh1dKmbMZTOK4G6krPG2gMBue0ceRg_Yl9Bpy63IJahQeYriI55lgkUOhjpTYXtuMLEfIuBDfXVUgCrDiwA50qmocBXcyRYflbbI6Po7PP4hrnVT0Clf0vjZi6o" }
Token Introspection
The OAuth 2.0 Token Introspection extension defines a protocol that returns information about an access token, intended to be used by resource servers or other internal servers.
POST Authorization: Basic <client_id as username, client_credentials as password> Content-Type: application/x-www-form-urlencoded POST Body: token=<access_token>&code=s7L4Zb&token_type_hint=access_token https://cloudentity.local.cloudentity.com/oauth/introspect
All clients does not get access to token introspection by default. It needs to be assigned during registration or set up an admin
All RS gets access to token introspection by default.Currently client id and cred for RS is not exposed via UI, contact CE admin to get the details
{ "active": true, "scope": "address phone openid profile offline_access email", "expires_at": "2018-05-24T19:37:55+0000", "exp": 1527190675, "sub": "2ab9f02c-aa46-48d7-a519-ccdaa5e9e0cc", "user_id": "admin@cloudentity.com", "client_id": "4aeabda1-5b8b-462f-8bca-2b78183e2342", "token_type": "Bearer" }
If accessToken is invalid
{ "active": false }
If introspection not allowed, then HTTP 403
OpenID Connect
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
OpenID Connect allows clients of all types, including Web-based, mobile, and JavaScript clients, to request and receive information about authenticated sessions and end-users. The specification suite is extensible, allowing participants to use optional features such as encryption of identity data, discovery of OpenID Providers, and session management, when it makes sense for them.
The OpenID Connect protocol, in abstract, follows the following steps.
-
The RP (Client) sends a request to the OpenID Provider (OP).
-
The OP authenticates the End-User and obtains authorization.
-
The OP responds with an ID Token and usually an Access Token.
-
The RP can send a request with the Access Token to the UserInfo Endpoint.
-
The UserInfo Endpoint returns Claims about the End-User.
OIDC Terminology
OIDC uses following terms and its important to understand these terms while talking about the actors, specifications and functionality.
OpenID Provider (OP) |
OAuth 2.0 Authorization Server that is capable of Authenticating the End-User and providing Claims to a Relying Party about the Authentication event and the End-User. In other words, its a system that offers authentication as a service. |
Relying Party (RP) |
Relying Party is an OAuth 2.0 client application that requires user authentication and claims from an OpenID Provider |
ID Token |
JWT that contains Claims about the Authentication event. It MAY contain other Claims. |
Scope |
Scopes are space-separated lists of identifiers used to specify what access privileges are being requested |
Claim |
Piece of information asserted about an entity that is included in the ID token |
OpenID Provider
Cloudentity OIDC service can act as an OpenID Provider with capability to authenticate users using simple and advanced authentication schemes.
Relying Party
Cloudentity supports registration of relying party applications via Cloudentity Application Services. These services allows to register applications of type OAuth2.0
ID Token
ID Token is a JSON Web Token that contains claims about user authentication events. ID Token JWTs are Base64 encoded JSON objects with three sections:
-
Header
-
Claims Set
-
JSON Web Signature (JWS).
The sections are separated in the JWT by a period ('.'). The Header must at least contain the algorithm that is used to sign the JWT (the alg claim).
Cloudentity ID Token
Cloudentity flow returns ID Token as per OIDC specifications
ID Token returned by authorization code flow is a JWT with below structure.
{ "sub": "2ab9f02c-aa46-48d7-a519-ccdaa5e9e0cc", "email_verified": true, "address": { "street_address": "2815 2nd Ave, Suite 390", "country": "US", "locality": "Seattle", "region": "WA", "postal_code": "98121" }, "kid": "oidc", "iss": "https://cloudentity.local.cloudentity.com/oauth/", "phone_number_verified": true, "preferred_username": "admin@cloudentity.com", "given_name": "Admin", "aud": "4aeabda1-5b8b-462f-8bca-2b78183e2342", "auth_time": 1527184392, "name": "Admin Cloudentity", "phone_number": "18887968341", "exp": 1527188210, "iat": 1527184610, "family_name": "Cloudentity", "jti": "1c54a89f-8c63-43d0-a26a-3526cf979f1f", "email": "admin@cloudentity.com" }
Scopes
Scopes are space-separated lists of identifiers used to specify what access privileges are being requested. For OpenID Connect, scopes can be used to request that specific sets of information be made available as Claim Values.
OpenID Connect defines following scopes
profile |
This scope value requests access to the End-User’s default profile Claims, which are: name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, and updated_at |
access to the email and email_verified claims |
|
address |
access to the address claim |
phone |
access to the phone_number and phone_number_verified claims |
Multiple scope values MAY be used by creating a space delimited, case sensitive list of ASCII scope values.
Claims requested by the scopes are returned either via UserInfo Endpoint ( when response_type issues an accessToken) ID Token ( when response_type=id_toke; in this case there is no accessToken issued)
Claim
The following claims are required claims about the authentication event:
aud (Audience): Must contain the client identifier of the RP registered at the issuer. iss(Issuer): The issuer identifier of the OP. exp (Expiration time): The RP must validate the ID token before this time. iat (Issued at): The time at which the ID token was issued. The following claims are required claims about the user:
sub (Subject): A locally unique and permanent (never reassigned) identifier of the user at the issuer. Optional claims about the user can include first_name, last_name, picture, gender, etc.
OIDC Authentication flows
OpenID Connect provider performs authentication to log in the End-User. The Authentication result is returned in an ID Token and the authentication flows piggyback on standard OAuth2.0 flows with some specific parameter values to denote that the request is an OIDC request.
Authentication can follow one of three paths:
-
Authorization Code Flow
-
Implicit Flow
-
Hybrid Flow
The flows determine how the ID Token and Access Token are returned to the Client.
The flow used is determined by the response_type value contained in the Authorization Request. These response_type values select these flows:
response_type |
Flow |
code |
Authorization Code Flow |
id_token |
Implicit Flow |
id_token token |
Implicit Flow |
code id_token |
Hybrid Flow |
code token |
Hybrid Flow |
code id_token token |
Hybrid Flow |
Authorization Code Flow
Authentication request
Mandatory OIDC specified request parameters
Request Parameters |
Description |
scope |
OpenID Connect requests MUST contain the openid scope value |
response_type |
value must be code |
client_id |
OAuth 2.0 Client Identifier valid at the Authorization Server |
redirect_uri |
Redirection URI to which the response will be sent. This URI MUST exactly match one of the Redirection URI values for the Client pre-registered at the OpenID Provider |
Optional OIDC specified request parameters
Request Parameters |
Description |
Supported by Cloudentity |
state |
Opaque value used to maintain state between the request and the callback |
Y |
response_mode |
Informs the Authorization Server of the mechanism to be used for returning parameters from the Authorization Endpoint. |
Y |
nonce |
String value used to associate a Client session with an ID Token, and to mitigate replay attacks. |
Y |
display |
ASCII string value that specifies how the Authorization Server displays the authentication and consent user interface pages to the End-User. |
N |
prompt |
Space delimited, case sensitive list of ASCII string values that specifies whether the Authorization Server prompts the End-User for reauthentication and consent. |
Partial |
max_age |
Maximum Authentication Age. Specifies the allowable elapsed time in seconds since the last time the End-User was actively authenticated by the OP. If the elapsed time is greater than this value, the OP MUST attempt to actively re-authenticate the End-User. |
Y |
ui_locales |
End-User’s preferred languages and scripts for the user interface, |
N |
id_token_hint |
ID Token previously issued by the Authorization Server being passed as a hint about the End-User’s current or past authenticated session with the Client |
N |
login_hint |
Hint to the Authorization Server about the login identifier the End-User might use to log in |
N |
acr_values |
Requested Authentication Context Class Reference values |
Y |
Implicit Flow
Hybrid Flow
NOT SUPPORTED
UserInfo
Once a user has an accessToken the are able to access userinfo using the accessToken as part of OIDC specifications
POST Authorization: Bearer <accessToken> https://cloudentity.local.cloudentity.com/oauth/userinfo
Success
{ "sub": "2ab9f02c-aa46-48d7-a519-ccdaa5e9e0cc", "name": "Admin Cloudentity", "preferred_username": "admin@cloudentity.com", "given_name": "Admin", "family_name": "Cloudentity", "email": "admin@cloudentity.com", "email_verified": true, "phone_number": "18887968341", "phone_number_verified": true, "address": { "street_address": "2815 2nd Ave, Suite 390", "locality": "Seattle", "region": "WA", "postal_code": "98121", "country": "US" } }
Failure
HTTP 401 Unauthorized { "error": "invalid_token", "error_description": "Invalid access token: eyJraWQiOiJvaWRjIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIyYWI5ZjAyYy1hYTQ2LTQ4ZDctYTUxOS1jY2RhYTVlOWUwY2MiLCJzY29wZSI6ImFkZHJlc3MgcGhvbmUgb3BlbmlkIGVtYWlsIHByb2ZpbGUgb2ZmbGluZV9hY2Nlc3MiLCJpc3MiOiJodHRwczpcL1wvY2xvdWRlbnRpdHkubG9jYWwuY2xvdWRlbnRpdHkuY29tXC9vYXV0aFwvIiwiZXhwIjoxNTI3MTg4MjEwLCJpYXQiOjE1MjcxODQ2MTAsImp0aSI6ImMxODBiM2ZlLTZjZDUtNGZiZC1iYzQ4LTFiNjRlOGUwZWM1MyJ9.gh2eVA7sw8DslbzdL7407Z5GQSoqaBUZuNE1_gUw5abWqzhmm0BkcykpLdWwIdkPZONDLJ4ozaVVJ7RbEV1zAY7Q_eLhkFQVfXKNbb65jP-S6IH2yhcoS9IjUySL0EqQCZ5RTDlezNpP4-5aVIBZr2QLd4oCa5XfaTE1rUAlmg8" }
Dependencies
OAuth and OIDC services are tied tightly into a range of Cloudentity use-cases. This section provides a high-level overview of some of the other tools and third-party components required to stand up this service.
Other UST Tools
As part of the Cloudentity platform, OAuth and OIDC rely on other components to function. The following may need to be set up in your environment.
-
TrUST™ Engine: The TrUST™ Engine is the core of policy management and is required in order to enforce OAuth and OIDC security policies.
-
Session Grid: The Session Grid support high availability for token management and enforcement. Underlying the Session grid is the Distributed Data Store which supports multi-datacenter distribution and storage of tokens to ensure the fastest response times at verificaiton and enforcement.
-
User Self Service (Optional): As part of the developer experience, the User Self Service UI provides an easy to follow interface to set up services and generate OAuth and OIDC credentials.
-
Services Grid: Application Service stores information about applications and exposes set of APIs to manage them.
Notable APIs
Cloudentity provides integrations for authorization and enforcement, but for use cases that require additional integration or functionality we provide direct access to the underlying APIs.
-
oidcService: The oidcService provides generation, current state, and revocation endpoints for tokens
-
applicationService: The applicationService is a robust API to manage and monitor security around specific services (or applications) but at a minimum is used to register services, generate clientIds and secrets and grant basic permissions to the service.
Third Party Components
Underlying the OAuth and OIDC server are a number of third party services.
Component Name |
oidc-service |
MicroService Type |
(Spring Boot)Java |
Containerized available |
yes |
Dependency type |
direct |
-
Cloudentity Session Store
Cloudentity uses session store instance to share spring sessions for Cloudentity OIDC microservice.
Component Name |
orchis-session-store |
MicroService Type |
(Hazelcast)Java |
Containerized available |
yes( Not recommended) |
Dependency type |
direct |