Getting Started with the Identity Domains REST API
The identity domains REST API securely manage resources, including identities and configuration data. Support for OpenID Connect allows integration with compliant applications and identity domains. The OAuth2 service provides an API infrastructure for authorization that supports a range of token grant types that enable you to securely connect clients to services.
The identity domains REST API supports SCIM 2.0 compliant endpoints with standard SCIM 2.0 core schemas and Oracle schema extensions to:
-
Manage users, groups, and apps.
-
Perform identity functions, including password generation and reset.
-
Perform administrative tasks including bulk operations and job scheduling.
-
Configure settings for an identity domain including multifactor authentication, branding, and notification templates.
This guide contains the following sections:
- Endpoints Deprecation Notices: Learn about endpoints deprecation notices for identity domains.
- Quick Start: Quickly get started with the identity domains REST API by completing prerequisites, installing curl, and setting up authorization to manage your identity domain resources such as users, groups, and applications.
- API Rate Limits: Understand the rate limiting for APIs for different identity domain types.
- Structuring Resource Requests: Learn the guidelines for building send requests in an identity domain.
- Using cURL: Learn how to use cURL to access the REST APIs.
- Managing Authorization Using the API: Learn how to use an OAuth client to access identity domains REST API. The identity domains REST API isn't accessible using only an identity domain username and password. To access the identity domains REST API, you need an OAuth2 access token or an API key to use for authorization.
- API Use Cases: Step through typical use cases using the identity domain REST APIs.
The following resources aren't in this guide but are also available to you.
When using the identity domains user interface:
- To administer IAM in tenancies with identity domains, see Oracle Cloud Infrastructure Identity and Access Management.
- For user self-service instructions, such as setting up MFA, see the IAM User Guide.
When using the API or CLI:
- To manage identity domains (for example, creating or deleting a domain), see IAM API.
- To manage resources within an identity domain, for example, users, dynamic resource groups, groups, and identity providers, see Identity Domains CLI.
Endpoints Deprecation Notices
Read the endpoint deprecation notices for identity domains in IAM.
To review details about Oracle Cloud Infrastructure breaking changes, such as deprecated features, deprecated APIs, and service behavior changes, see IAM Service Change Announcements.
Quick Start
Quickly get started with the identity domains REST API by completing prerequisites, installing curl, and setting up authorization to manage your identity domain resources such as users, groups, and applications.
Prerequisites
- Buy an Oracle Cloud Subscription: See Buy an Oracle Cloud Subscription.
- Activate your order: Set up your account or activate your order. See Activate Your Order from Your Welcome Email in Buy an Oracle Cloud Subscription.
- Obtain the appropriate account credentials and authorization to access identity domain APIs from your identity domain administrator:
-
To sign in to your identity domain. See your identity domain administrator to obtain your username, password, and identity domain name.
-
To use the API without a user account. Administrators can use the identity domains API without a user account in the identity domain. To use the identity domains API without a user account, request a client ID and a client secret from the identity domain administrator.
-
Step 1: Sign In to Your Identity Domain
After you activate your account, you're sent sign-in credentials and a link to the home page of your identity domain. Select the link in the email, and then enter the provided sign-in credentials. Your identity domain home page appears. See Sign In to the Console.
Step 2: Install cURL
The examples within this document use the cURL command line tool to demonstrate how to access the identity domains REST API.
To connect securely to the server, you must install a version of cURL that supports SSL and provide an SSL certificate authority (CA) certificate file or bundle to authenticate against the Verisign CA certificate. For more information about:
-
Using cURL, see Using cURL.
-
Authorization, see Managing Authorization Using the API.
-
In a browser, navigate to the cURL home page at http://curl.haxx.se/download.html.
-
On the cURL Releases and Downloads page, find the SSL-enabled version that corresponds to your OS, and then select the link to download the ZIP file.
-
Install the software.
-
Navigate to the cURL CA Certs page at http://curl.haxx.se/docs/caextract.html, and then download the ca-bundle.crt SSL certificate authority (CA) certificate bundle into the folder where you installed cURL.
-
Set the cURL environment variable:
-
Open a command window.
-
Navigate to the directory where you installed cURL.
-
Set the cURL environment variable (CURL_CA_BUNDLE) to the SSLCA certificate bundle location. For example:
C:\curl> set CURL_CA_BUNDLE=ca-bundle.crt.
-
Step 3: Understand the Resource URL Format
You access the identity domains REST API using a URL, which includes the REST endpoint, the resource that you want to access, and any query parameters that you want to include in a request.
The basic endpoint for the identity domains REST API is:
https://<domainURL>/admin/v1/
See Send Requests for specific details on building these URLs.
Step 4: Set Up Authorization
You need to generate the access token that you can then use to authorize requests that you send to the identity domains REST API. See Managing Authorization Using the API.
You're now ready to send requests to an identity domain using cURL.
Step 5: Manage Your Identity Domain Resources
Begin using the REST API to manage overall identity domain configurations and identities and resources.
API Rate Limits
Understand the rate limiting for APIs for different identity domain types.
Oracle APIs are subject to rate limiting to protect the API service usage for all Oracle's customers. If you reach the API limit for the identity domain type, then IAM returns a 429 error code.
Rate Limits for all Identity Domain Types
| API Group | Per | Free | Oracle Apps | Oracle Apps Premium | Premium | External User |
|---|---|---|---|---|---|---|
| AuthN | second | 10 | 50 | 80 | 95 | 90 |
| AuthN | minute | 150 | 1000 | 2100 | 4500 | 3100 |
| BasicAuthN | second | 10 | 100 | 160 | 95 | 90 |
| BasicAuthN | minute | 150 | 3000 | 4000 | 4500 | 3100 |
| Token Mgmt | second | 10 | 40 | 50 | 65 | 60 |
| Token Mgmt | minute | 150 | 1000 | 1700 | 3400 | 2300 |
| Others | second | 20 | 50 | 55 | 90 | 80 |
| Others | minute | 150 | 1500 | 1750 | 5000 | 4000 |
| Bulk | second | 5 | 5 | 5 | 5 | 5 |
| Bulk | minute | 200 | 200 | 200 | 200 | 200 |
| Import and export | day | 4 | 8 | 10 | 10 | 10 |
The maximum number of Identity Propagation Trust objects that can be created is restricted to 30. Contact support if the limit needs to be increased. For more information on object limits, see IAM Identity Domain Object Limits.
APIs in API Groups
API limits apply to the total of all APIs within a group.
/sso/v1/user/login/sso/v1/user/secure/login/sso/v1/user/logout/sso/v1/sdk/authenticate/sso/v1/sdk/session/sso/v1/sdk/idp/sso/v1/sdk/secure/session/mfa/v1/requests/mfa/v1/users/{userguid}/factors/oauth2/v1/authorize/oauth2/v1/userlogout/oauth2/v1/consent/fed/v1/user/request/login/fed/v1/sp/sso/fed/v1/idp/sso/fed/v1/idp/usernametoken/fed/v1/metadata/fed/v1/mex/fed/v1/sp/slo/fed/v1/sp/initiatesso/fed/v1/sp/ssomtls/fed/v1/idp/slo/fed/v1/idp/initiatesso/fed/v1/idp/wsfed/fed/v1/idp/wsfedsignoutreturn/fed/v1/user/response/login/fed/v1/user/request/logout/fed/v1/user/response/logout/fed/v1/user/testspstart/fed/v1/user/testspresult/admin/v1/SigningCert/jwk/admin/v1/Asserter/admin/v1/MyAuthenticationFactorInitiator/admin/v1/MyAuthenticationFactorEnroller/admin/v1/MyAuthenticationFactorValidator/admin/v1/MyAuthenticationFactorsRemover/admin/v1/TermsOfUseConsent/admin/v1/MyTermsOfUseConsent/admin/v1/TrustedUserAgents/admin/v1/AuthenticationFactorInitiator/admin/v1/AuthenticationFactorEnroller/admin/v1/AuthenticationFactorValidator/admin/v1/MePasswordResetter/admin/v1/UserPasswordChanger/admin/v1/UserLockedStateChanger/admin/v1/AuthenticationFactorsRemover/admin/v1/BypassCodes/admin/v1/MyBypassCodes/admin/v1/MyTrustedUserAgents/admin/v1/Devices/admin/v1/MyDevices/admin/v1/TermsOfUses/admin/v1/TermsOfUseStatements/admin/v1/AuthenticationFactorSettings/admin/v1/SsoSettings/admin/v1/AdaptiveAccessSettings/admin/v1/RiskProviderProfiles/admin/v1/Threats/admin/v1/UserDevices/session/v1/SessionsLogoutValidator/ui/v1/signin
/admin/v1/HTTPAuthenticator/admin/v1/PasswordAuthenticator
/oauth2/v1/token/oauth2/v1/introspect/oauth2/v1/revoke/oauth2/v1/device
/job/v1/JobSchedules?jobType=UserImport/job/v1/JobSchedules?jobType=UserExport/job/v1/JobSchedules?jobType=GroupImport/job/v1/JobSchedules?jobType=GroupExport/job/v1/JobSchedules?jobType=AppRoleImport/job/v1/JobSchedules?jobType=AppRoleExport
/admin/v1/Bulk/admin/v1/BulkUserPasswordChanger/admin/v1/BulkUserPasswordResetter/admin/v1/BulkSourceEvents
Any API not in one of the other API Groups is included in the Other API Group
Other Restrictions
These restrictions are for Bulk, Import, and Export for all tiers:
- Payload size: 1 MB
- Bulk API: 50 operations limit per call
- Only one of these can be run at a time:
- Import: For Users, Groups & App Role Memberships
- Full sync from apps
- Bulk APIs
- Export: For Users, Groups & App Role Memberships
- CSV Import: 100 K rows limit per CSV & Max file size: 10 MB
- CSV Export: 100 K rows limit
Using cURL
cURL is an open source, command line tool for transferring data with URL syntax, supporting various protocols including HTTP and HTTPS. The examples within this document use cURL to demonstrate how to access the identity domains REST API.
Using cURL to Access the REST APIs
-
Install cURL. See Step 2: Install cURL.
-
In a command window, set the cURL environment variable,
CURL_CA_BUNDLE, to the location of your local CA certificate bundle. For information about CA certificate verification using cURL, see: http://curl.haxx.se/docs/sslcerts.html. -
Invoke cURL and specify one or more of the following command line options, as required, to direct its execution.
-d, --data @file.json: Identifies the request document, in JSON format, on the local machine.-F, --form @file.json: Identifies form data, in JSON format, on the local machine.-H, --header: Defines the request header in the format of HEADER: VALUE. The header values depend on which endpoint that you're accessing.-
The content type of the request document.
-
The
X-Client-ID,API_KEY_ID,for OAuth 2.0 authorization -
The
X-Client-Secret,API_KEY_SECRET,for OAuth2.0 authorization
-
-i: Displays response header information.-X: Indicates the HTTP request method(DELETE, GET, POST, PATCH, orPUT).If this option is omitted, the default is GET.
The cURL Command URL
The URL used with the cURL command is the same as that described in Send Requests except that you must replace spaces in the URL with plus characters (+) and replace quotes (") with %22.
Any characters in a URL that are outside the ASCII character set, such as spaces and quotes, must be URL encoded. For example, the following URL contains a filter query that searches for a user with a username either containing jen or starting with bj. Note that it contains spaces.
https://<domainURL>/admin/v1/Users?filter=userName co "jen" or userName sw "bj"
To use this URL in a cURL command line, you would change it to:
https://<domainURL>/admin/v1/Users?filter=userName+co+%22jen%22+or+userName+sw+%22bj%22
cURL Command for Sending a GET Request
curl
-H "Accept: application/scim+json"
-H "Authorization: Bearer <really long access token here>"
-G https://<domainURL>/admin/v1/Groups?filter=displayName+co+%22admin%22"
cURL Command for Sending a POST Request
curl
-H "Content-Type: application/scim+json"
-H "Authorization: Bearer <really long access token here>"
-d '{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],"userName":"bjensen@example.com","name": {"familyName":"Jensen","givenName": "Barbara","middleName": "Jane"},"emails": [{"value": "bjensen@example.com","type": "work","primary": true}]}' "https://<domainURL>/admin/v1/Users"
Managing Authorization Using the API
The identity domains REST API supports both token-based authorization and OCI request signatures. For security reasons, the identity domains REST API isn't accessible using only the username and password that you use to sign in to the identity domain. To access the identity domains REST API, you need an OAuth2 access token or an API key to use for authorization.
identity domains REST API use the OAuth 2.0 protocol for authentication and authorization and support these common authorization scenarios:
-
Web server
-
Mobile
-
JavaScript applications
The Authorization section discusses the OAuth 2.0 scenarios that identity domains support.
This section contains the following topics:
Registering a Client Application
An application must be registered as an OAuth 2 Client using the identity domain. OAuth clients are HTTP clients that can get and then use an access token.
Complete the following steps to use an OAuth client to access identity domains REST API:
-
Sign in to the identity domain using the username and password found in your Welcome email.
-
Create an OAuth client application and make note of the client ID and client secret.
Note
When you configure the OAuth client application, select the application roles that you want to assign to the application. This enables your application to access the REST APIs that each of those assigned application roles can access. Each application role has scopes assigned to it that define an even more fine-grain level of access to API operations. For example, select Identity Domain Administrator from the list. All REST API operations available to the identity domain administrator will be accessible to the application. -
Use the client ID and client secret to request an access token from the IAM OAuth Service.
-
Include the access token in the appropriate HTTP header when you make REST API calls.
More Information
- For more information on registering a client application, see Registering a Client Application.
-
For more information on grant types, see Access Grant Types.
-
To walk through the steps yourself, see Using OAuth 2 to Access the REST API.
-
For a list of all available endpoint operations and the application roles required to access them, see AppRole Permissions.
-
For a list of which AppRoles can be granted to both clients and users and which can only be granted to clients, see AppRoles That Can Be Granted to Clients and Users.
Security Recommendations
To securely integrate your applications with identity domains using OAuth, you must implement security controls recommended by the standard.
The security controls may be considered mandatory or optional depending on your application confidentiality, integrity, and availability requirements.
Security controls implemented across all OAuth participants, which includes the Authorization Server ( IAM), the Resource Owner (user), the Client, and the Resource Server applications
Confidentiality of key information: code, access_token, refresh_token, client credentials, and user credentials
Server authentication established between OAuth participants (to avoid impersonation attacks)
Proper information validation for any request (especially for JSON Web Token (JWT) access tokens)
Use of tokens with minimal scopes and timeout (to reduce the exposure in case of disclosure and to support the token revocation)
Use of typical information security principles such as least privilege
Resources
For more information about OAuth security, access the following links:
We recommend that you monitor security proactively so that you can quickly identify new security threats.
Security Recommendations Checklist
This page lists the most relevant security recommendations as a checklist, so that you can validate your application security and address the security items according to your expectations.
Encryption
-
Use TLS in Client and Resource Server Applications
The use of TLS with all applications provides confidentiality in communications between identity domain, resource owners, client applications, and resource server applications. This prevents eavesdropping during transmission of the authorization code, access tokens, refresh tokens, client credentials, and user credentials, and preventing replay attacks.
-
Establish Server Authentication (HTTPS with Trusted CA Validation)
Server authentication allows clients, resource servers, and resource owners to establish communication between themselves and with an identity domain after verifying the public certificate against the trusted CA.
If the server fails to provide a trusted certificate (provided by a trusted CA and with a matching hostname), the communication is considered a man-in-the-middle attack.
Server authentication prevents spoofing, proxying, man-in-the-middle, and phishing attacks to capture authorization codes, access tokens, client credentials, and user credentials.
-
Consider Using a Trusted Assertion with Identity Domains
Critical security clients can use a client assertion with key cryptography (instead of a client secret) for authentication.
-
Protect the Redirect URI with HTTPS and Trusted CA Validation
HTTPS and using trusted CA validation prevents authorization "code" phishing and user session impersonation.
Administration
-
Configure Applications Following the Least Privilege Principle
Applications should be configured in an identity domain with only the minimum rights needed for their operation.
Narrowing down the scope, flows, grant types, and operations improves the security posture and reduces the impact of a compromised application.
-
Provide a Meaningful Name and Description for Applications
The application information appears for users under the My Apps and the consent pages.
The use of meaningful application names and descriptions may prevent users from making mistakes during consent authorization and also contributes to better audit reporting.
-
Provide a Meaningful Description for Scopes
The scope description appears on the consent page. Explaining the scope, which the user is about to grant, in an understandable way prevents the user from making mistakes during authorization and contributes to better audit reporting.
-
Avoid Scopes Provided Without Consent
To leverage transparency and rely on the resource owner, provide scopes without permission only when a scope is mandatory, and the user must not be able to deny it.
-
Reduce the Access Token Time Out and Use Refresh Tokens
Identity domains support JWT, an access token that can be validated in resource servers without checking the token in the identity domain. Because of this, access tokens with long duration can't be easily revoked.
To implement timely revocation, you can configure the access token with a short lifetime, and then use the refresh token for requesting new access tokens. To perform a timely revocation, you need to revoke the refresh token.
-
Rotate the Application's Client Secrets
For security critical implementations, implement a client secret rotation. This reduces the risk of getting a compromised client secret explored.
Resource Owner (User)
-
Keep the Resource Owner Informed
Scope use with consent provides transparency to the resource owner and prevents applications from requesting scopes that aren't required.
-
User Awareness
Teach users how to protect their credentials and identify client, resource server application, and identity domain legitimacy (especially when authentication and consent pages appear). This reduces the risk of phishing attacks and the compromise of user credentials.
Application Development
-
Protect Codes, Access Tokens, Refresh Tokens, and Client Credentials
Applications must preserve the confidentiality of codes, access tokens, refresh tokens, and client credentials. When you develop the application, consider the following measures (among other application security measures):
-
Don't store codes (use the code only during runtime to obtain the access token)
-
Keep access tokens in transient memory and limit their grants
-
Store refresh tokens and client credentials in secure places that can be accessed only by the application
-
-
Protect the Redirect URL
The redirect URL (from where the identity domain retrieves the authorization code) is considered a key component for OAuth security. Be careful when you define this URL to avoid threats such as cross site request forgery and denial of service.
-
Read Tokens from the Native Apps File System
Attackers may try to get file system access on the device and read the refresh tokens using a malicious application. To reduce this risk, store secrets in secure storage and use device lock to prevent unauthorized device access.
-
Implement Controls for Cloned and Stolen Devices with Native Apps
To reduce risks when a device with Native Apps gets cloned or stolen, use device lock to prevent unauthorized access and revoke refresh tokens.
-
Validate Application Security Prior to Publication
Test the application and its hosting environment security before publishing the application to reduce vulnerabilities. Threats related to application hosting and development aren't addressed by identity domains. These threats include but aren't limited to indirect access to application databases and storage, select-jacking, cross-site scripting, script/SQL injection, and information confidentiality flows on the application.
-
Apply Least Privilege During Scope Request
Client applications should request tokens that contain only scopes that it will possibly or actually use.
The use of the
urn:opc:idm:__myscopes__ scope, although convenient, may retrieve more tokens than needed by the client application.A token with extensive scopes can increase the security impact when a token is compromised.
See Scopes for information about using the scope parameter and an access token to grant different levels of access to identity domains.
-
Validate JWT Tokens
When receiving an access token (JWT) from any party (except the identity domain server in a direct request from your application), validate the JWT following the JWT Profile for OAuth 2.0 Client Authentication and Authorization Grants and the JWT RFCs.
See Token Validation for more information on how to validate the token.
Note
Resource servers must process information only after the entire JWT validation is performed. -
Receive JWT Tokens Properly
Resource server applications must receive the access token using only the
Authorization: bearer <token>header to avoid threats related to parameter caching. -
Implement 2-Way TLS Between Client and Resource Server Applications
For security critical applications, you can implement a 2-way TLS between client and resource server applications to reduce the risk of denial of service (DoS) and impersonation attacks.
Don't write applications that collect authentication information directly from users.
-
Prevent Select-Jacking
For newer browsers, avoid iFrames during authorization by enforcing the use of the
X-FRAME-OPTIONSheader.For older browsers, JavaScript frame-busting techniques can be used but may not be effective in all browsers.
-
Avoid the Use of Resource Owner Password Credentials
The resource owner flow allows a client to request an access token using an end user's ID, password, and the client's own credentials. This grant type presents a higher risk because:-
It's in charge of collecting the user credentials on the client application (maintains the UID/password anti-pattern).
-
Doesn't present a consent screen for scope requests.
Except for migration reasons, avoid the use of this grant type.
-
-
Use the
Cache-Control="no-store"HeaderThis header minimizes the risk of not protecting authenticated content and leaking confidential data in HTTP proxies.
-
Avoid Requests with Sensitive Information Sent Using URL Parameters
The URL parameters (used on GET requests) can be logged in any component between applications such as application logs, proxy servers, firewalls, and network edge components.
Identity domains implement alternative search REST endpoints using POST that addresses this risk. See the Query Parameters page for more information.
Supported Tokens
A token is used to make security decisions to authorize a user and to store tamper-proof information about a system entity in an identity domain.
Identity domains support JSON Web Tokens (JWT). A JWT is a JSON-based open standard (RFC 7519) that defines a compact and self-contained way for securely sending information between parties as a JSON object. This information can be verified and trusted because it's digitally signed. JSON Web Tokens consist of three parts separated by periods (xxxx.yyyy.zzzz):
-
Header. Consists of two parts: the type of token (JWT) and the hashing algorithm being used, such as SHA256
-
Payload. Contains the claims (the token data)
-
Signature. Consists of the encoded token header and the encoded payload signed with the identity domain private key. The signature is used to verify that the sender of the JWT is who it says it's and ensures that the message wasn't changed along the way.
Identity domains support three different tokens: identity token, access token, and client assertion.
To access detailed information on each supported token, select any of the following links:
For information about token expiration go to:
Identity Token
An Identity Token is an integrity-secured, self-contained token (in JSON Web Token (JWT) format) that's defined in the OpenID Connect standard containing claims about the end user. The Identity Token is the primary extension that OpenID Connect makes to OAuth 2.0 to enable authentication in an identity domain.
The Identity Token JWT consists of three components, a header, a payload, and the digital signature. Following the JWT standard, these three sections are Base64URL encoded and separated by periods.
OpenID Connect requests must contain the
openid scope value. OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows an IAM identity domain client application (registered as an OAuth 2 client with client ID and client secret) to verify the identity of the end user based on the authentication performed by an Authorization Server (AS), and to obtain basic profile information about the end user in an interoperable, 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. See OpenID Connect for more information.
| Name | Value |
|---|---|
amr
|
Authentication Methods References. JSON array of strings that are identifiers for authentication methods used in the authentication. For example, values might indicate that both password and OTP authentication methods were used. |
at_hash
|
OAuth 2 Access Token hash value. |
aud
|
Identifies recipients for which this ID Token is intended. Must be the OAuth 2.0 client_id (per the OpenID Connect specification). This is the OAuth client name (app.name) that's making the request. Aud also contains the IAM identity domain Issuer, thereby turning the token type (IT) into an IAM identity domain User Assertion. |
authn_strength*
|
The value returned by Cloud SSO indicating Authentication Strength from AuthN Context. |
auth_time
|
The time (UNIX epoch time) when Cloud SSO actually authenticated the user (in seconds, coming from AuthN Context). |
azp
|
Authorized party. The party to which the ID Token was issued. If present, it MUST contain the OAuth 2.0 Client ID of this party. This claim is only needed when the ID Token has a single audience value and that audience is different than the authorized party. It may be included even when the authorized party is the same as the sole audience. The azp value is a case-sensitive string that contains a StringOrURI value. |
exp
|
The expiration time (UNIX epoch time) on or after which the ID Token
must not be accepted for processing. This value must be same as the
session_exp. |
iat
|
The time (UNIX epoch time) when the JWT was created (in seconds). UNIX Epoch Time is a JSON number representing the number of seconds from 1970-01-01T0:0:0Z as measured in Coordinated Universal Time (UTC) until the date/time. |
iss
|
The principal that issued the token:
https://<domainURL>
|
jti
|
The server-generated unique identifier for the JWT ID. |
nonce
|
The string value used to associate a client session with an ID Token and to mitigate replay attacks. This value is provided by Cloud Gate. |
session_exp*
|
The time (UNIX epoch time) when the Cloud SSO session expires (seconds, must be the same SSO's session expiration in AuthN context). |
sid
|
The session ID from Cloud SSO (255 maximum ASCII characters) from AuthN Context. |
sub
|
Identifies the user. The subject identifier is locally unique, never reassigned, and is intended to be consumed by the client: User Login ID (255 maximum ASCII characters). This is the user's login ID from AuthN Context. |
sub_mappingattr*
|
The attribute used to find the sub in the ID store. |
tok_type*
|
Identifies the token type: IT |
user_displayname*
|
The User Display Name (255 maximum ASCII characters) from AuthN Context. |
user_csr*
|
Indicates (true) that the user is a Customer Service Representative (CSR). |
user_id*
|
The user's IAM identity domain GUID from AuthN Context. |
user_lang*
|
The user's preferred language. |
user_locale*
|
The user's locale. |
user_tenantname*
|
The User Tenant Name (255 maximum ASCII characters). Tenant's GUID is specifically not saved in the token |
user_tz*
|
The user's time zone. |
Client/User JWT Assertion
An assertion is a package of information that facilitates the sharing of identity and security information across security domains. An assertion typically contains information about a subject or principal, information about the party that issued the assertion and when it was issued. It also contains information about the conditions under which the assertion is to be considered valid, such as when and where it can be used. The intent is to provide an alternative client authentication mechanism. Clients can build client assertions and use them as credentials rather than using the client ID and client secret in an OAuth token request.
Identity domains support the use of client and user assertions for authentication. The following information defines the format of the client assertion and the user assertion, including standard and custom claims. Names with (*) are proprietary to Oracle.
Client/User Assertion Headers
| Name | Value |
|---|---|
kid
|
Key identifier. Used to identify the trusted third-party certificate to validate the assertion signature. The x5t or kid claim must be present in the JWT assertion header. |
type
|
Type. Identifies the type of assertion, which is always JWT. |
alg
|
Algorithm. Identifies the specific type of JWT signing algorithm. This is a required header for the JWT assertion. Identity domains support RS256. |
x5t
|
Base64 URL encoded X.509 certificate sha1 thumbprint. This is used to identify specific certificates. The x5t or kid claim must be present in the JWT assertion header. |
JWT Body/Claims
| Name | Value |
|---|---|
sub
|
Subject. The principal that's the subject of the JWT: For client assertions, the client ID value must be the identity domain App name attribute. For user assertions, the claim value must be the username. |
iss
|
Issuer. The Client that's generating the assertions (identity domain App name attribute). This is a required claim for the assertion. |
aud
|
Audience. Identifies the recipients for which the JWT is intended. The identity domain URL (https://<domainURL>) must be one of the aud claim values. |
exp
|
Expiration. The time (UNIX epoch time) when the JWT assertion expires. This is a required claim for the assertion. |
iat
|
Issued at. The date when the assertion was issued. |
Sample JWT Client Assertion
{
"kid": "SampleOAuthClient_1",
"typ": "JWT",
"alg": "RS256",
"x5t": "fa4c3b48128f0a88cb8e3c37fbcd02d341080e4f33f081dc546886e7f4bc26aa"
}
{
"aud": ["https://<domainURL>/"],
"sub": "60da13c1-6f27-41e2-bc4e-9cdbccbb4251",
"iss": "60da13c1-6f27-41e2-bc4e-9cdbccbb4251",
"exp": "1598229425738",
"iat": "1440549425738",
"jti": "bbd28459-5ba9-4dfb-bfeb-8141eca853c4"
}
Sample JWT User Assertion
{
"kid": "SampleOAuthClient_1",
"typ": "JWT",
"alg": "RS256",
"x5t": "fa4c3b48128f0a88cb8e3c37fbcd02d341080e4f33f081dc546886e7f4bc26aa"
}
{
"aud": ["https://<domainURL>/"],
"sub": "test@oracle.com",
"iss": "60da13c1-6f27-41e2-bc4e-9cdbccbb4251",
"exp": "1598229425738",
"iat": "1440549425738",
"jti": "bbd28459-5ba9-4dfb-bfeb-8141eca853c4"
}
Generating User and Client Assertions Using a Signing Key
Before You Begin
- GlassFish javax.json-1.0.4 library
- JDK 8 to perform the base64 encoding/decoding.
Note: It's not necessary to generate a signed client assertion if the client can authenticate using client ID & client secret. You need to decide how to authenticate the client by using the client ID/client secret or by using PKI.
Assertion Generator Lightweight JDK8
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
/**
*
* Sample class to generate assertions suitable for IDCS jwt-bearer style OAuth
* Requires JDK8 in order to perform the Base64 encoding/decoding
*
* JSON dependency is javax.json-1.0.4.jar
* http://central.maven.org/maven2/org/glassfish/javax.json/1.0.4/javax.json-1.0.4.jar
*
* Assumptions - self-signed keypair generated using something like ..
*
* KEY_ALG=RSA
* SIG_ALG=SHA256withRSA
*
* ${JAVA_HOME}/bin/keytool -genkeypair -v -keystore .... -storetype PKCS12 -storepass .... \
* -keyalg ${KEY_ALG} -keysize 2048 -sigalg ${SIG_ALG} -validity 1825 \
* -alias ... -keypass .... -dname ...."
*
* Using client and user assertion output from this class, obtain access token using something like ....
*
* grant_type='urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer'
* user_assertion='XXXXXXX.YYYYYYY.ZZZZZZZZ'
* client_assertion_type='urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer'
* client_assertion='AAAAAAA.BBBBBBB.CCCCCCCC'
* client_id='31282cbe9858409ab5b5a6020e85ccb6'
* scope='urn:opc:entitlementid=999999999urn:opc:resource:consumer::all'
*
* oauth_payload="grant_type=${grant_type}&assertion=${user_assertion}&client_assertion_type=${client_assertion_type}&client_assertion=${client_assertion}&client_id=${client_id}&scope=${scope}"
*
* oauth_url='https://idcs-XXXXXXXXXXXX.YYYYYY.com/oauth2/v1/token'
*
* curl -i
-H "Content-Type:application/x-www-form-urlencoded;charset=UTF-8" --request POST ${oauth_url} -d ${oauth_payload}
*/
public class AssertionGeneratorLightweightJdk8
{
// Client certificate in raw form - obtained from the Generate Self-Signed Keypair section
static String CLIENT_CERT =
"MIIDtzCCAp+gAwIBAgIENeogPjANBgkqhkiG9w0BAQsFADCBizELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFzAVBgNVBAcTDlJlZHdvb2QgU2hvcmVzMRswGQYDVQQKExJPcmFjbGUgQ29ycG9yYXRpb24xDDAKBgNVBAsTA0lETTEjMCEGA1UEAxMac2xleHRjb21wMTMgQ0VDUyBBc3NlcnRpb24wHhcNMTgwODE1MTAyMDQ1WhcNMjMwODE0MTAyMDQ1WjCBizELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFzAVBgNVBAcTDlJlZHdvb2QgU2hvcmVzMRswGQYDVQQKExJPcmFjbGUgQ29ycG9yYXRpb24xDDAKBgNVBAsTA0lETTEjMCEGA1UEAxMac2xleHRjb21wMTMgQ0VDUyBBc3NlcnRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCT+xQU6S+KzjunLPFuvfpy86BxNcUJp8EppGORDR3VrjNH69G3hVF18gV9J/XAVtPApP4n+ZRRQvaFuzwjaXHf3vZ10wEu/N0RIE3zIq98CBMyRp2C8orTYuboN1pQGjieAEBHe2kp7Y1Jkc2UtircRHSpOBDp7KwuwLlHmlBXC4clF6nzFq8UZ9hg4UkA5+lDR70esRAEgrDxJpnSjp27cJFhZHP8oaLQ+ai4wvg9UReUns/mTcNwc6Acv/HPK+d9m9AEzj7ItAVYhnfhQVZ4fUr/AiAvAT43Pv0ZqEHlyByjqauIYp8O+kvtCC68A4mGMHDUNxvVq10Bs7SozaWzAgMBAAGjITAfMB0GA1UdDgQWBBT8O+7161UPiGFbrsEh0Rua0JJezTANBgkqhkiG9w0BAQsFAAOCAQEAAoh+ThSg3Jk4el/RHCOOJZ1pbSMKjmmzWC46Ca8tpjdJ4iaOYrXe+QQmyUvfp/hGcKdvbvex/Ot19d4TxMwNHxapxPfllKDd8WYzMdBc1th8JLxeGXHYfRhk1ImHQWDW9B1K2x2JC/03Wtg/d+Ipno97ydnzcz1+Ef1HEuG4A8WmXS2GBppldZxIeI4XMqi9nKxyDZX+WQPi6RgbpLkizY3krcHUbdwsuWKoc2JATST8XgUx5hw2znlFezt60+7uXnFbfU72WgYrzwrr8NWiR6d9LLP9t5R9odY2Q4WoifwzljkslpYZ0hjWFuvRdLK/XLzb0hLiU0m15oZz9kQWqw==";
// PKCS8 version of the private key in raw form - obtained from the Generate Self-Signed Keypair section
static String CLIENT_PRIVATE_KEY =
"MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCT+xQU6S+KzjunLPFuvfpy86BxNcUJp8EppGORDR3VrjNH69G3hVF18gV9J/XAVtPApP4n+ZRRQvaFuzwjaXHf3vZ10wEu/N0RIE3zIq98CBMyRp2C8orTYuboN1pQGjieAEBHe2kp7Y1Jkc2UtircRHSpOBDp7KwuwLlHmlBXC4clF6nzFq8UZ9hg4UkA5+lDR70esRAEgrDxJpnSjp27cJFhZHP8oaLQ+ai4wvg9UReUns/mTcNwc6Acv/HPK+d9m9AEzj7ItAVYhnfhQVZ4fUr/AiAvAT43Pv0ZqEHlyByjqauIYp8O+kvtCC68A4mGMHDUNxvVq10Bs7SozaWzAgMBAAECggEARy0C0bP/HAJqCtTBI4TZC6VGzG0SYrx/WiopgcEPUpHBNJymeGD1d4d7QGGSAHtCymwRmuSehB9zN4uBN38mOImjfbSJ4zHYmr4w//r08PFpWktAw5UpVNdDPPoyxEh4Zvaz9C3VvUb3KCWq/hZIsz1x51qCOCGQB8TG2TvN3K+BP0zzB0IPRqI7b3ydxLFJ8Hn9Y1HRd/8fi11wiPlHtVwMhKXrqnTiaZTayUW9ARPgLK4ZajtUM5FNC8PRTZqxkMge9qC4Q8067zuIMZhHeRR8bLS/5MHSae6/uR0vZOg9nWmRj6Zq33tlflaPcSer/RWlAY5AygQGFveVJc8fQQKBgQDN5jJQPyPcHN+mopJxO5P0c5f69sv8J4hG05qC1I66P5w+TkZZJQYJGMJbazrDmgHigcrbNdUnjYhrNyOipzaYaSye8FRrmgpTZY1nwlY5qj5HHi5GNjbMq/OJKbs46mBu3aSl3K1d0ujAv+rxUofd9PwNjmBMyfNr95h3Jmew0QKBgQC3/Qv02c0e4RrdWVfpi71AiUqmMQ/nKj1SVQ54XQU6FY0y9RTYENN7+b6mFYHJm9B9CkQPx4NsScmQK/ucvE1ZxZANeFaOENAiq06A+0tj31FGoDBIihVYUkHnrupiJz8ug+9c4jwUoho95V6/iLVnRu4a70Wc97N1LnGeG/QvQwKBgH7GXfRK7Cl7HbncH47YwCCji9BaZP682IvDfj9P4RGMWQeD6oy43x56wDDJtUT6bm6ou959JuFTo8tgB/D+Q/9TwsWZ9GDMV89Bl+9rGOwohnADhTp15wfeV/T8XOqOZRHeJqJ5XcWHNwh3IpGz3zQqw4cVQvYE4nx31siGPRIBAoGAIgDSRN472okfvejVJoR85YB6G1zV45Ma4ix2ECig3qs8/T3uLEBv1WnCok83PVtenL1Y9tGYqFq6tbprNfxXD1BD3zluRbM1xDKEv7GxrTOIgdT5F27tovUQ2RCqoJlARAh+JFxrXiTXVLkfWaaaYAvr1W6DHw9oSy/aL65a4qECgYB85lE4sKn2g97W7i51w7rNZwRPr0WcwDz2ecuXOFaURw9g/+8duD9Cq4zMcxwNSjc/kPbxNrY3PKcbZm2Guq6KSiF6Svg8valbMuEadOar/4CZeGyHy8tfYHRGxHP5w2Bh1HbCVQvjC3IzAZJi6pjknz7HuIdOkuhCcSRGjLhurQ==";
static String KEY_ID = "cecsassertionkey"; // the alias/key we registered the public certificate under
static String CLIENT_ID = "31282cbe9858409ab5b5a6020e85ccb6"; // the trusted client ID
static String USER_NAME = "abc@xyz.com"; // the user whom we want to assert identity for
static List<String> AUDIENCE_LIST = Arrays.asList("<domainURL>/");
// JSON Web Token Claims ...
private static final String ISSUER_CLAIM = "iss";
private static final String SUBJECT_CLAIM = "sub";
private static final String AUDIENCE_CLAIM = "aud";
private static final String EXPIRATION_TIME_CLAIM = "exp";
private static final String NOT_BEFORE_CLAIM = "nbf";
private static final String ISSUED_AT_CLAIM = "iat";
private static final String JWT_ID_CLAIM = "jti";
// JSON Web Token Header Parameters
private static final String ALGORITHM_HEADER = "alg";
private static final String KEY_ID_HEADER = "kid";
private static final String X509CERT_SHA1_HEADER = "x5t";
private static final String X509CERT_SHA256_HEADER = "x5t#S256";
public static void main(String[] args) throws Exception
{
Date now = new Date();
Date expirationTime = new Date((60 * 60 * 1000) + now.getTime()); // (1 hour from current time)
JsonObject clientClaims = buildJWTClaims(CLIENT_ID, CLIENT_ID, AUDIENCE_LIST, expirationTime, now, now,
UUID.randomUUID().toString());
System.out.println(clientClaims.toString());
// Call the method to generate the assertions for both client and user assertions
String clientAssertion = generateAndSignJWTAssertion(CLIENT_PRIVATE_KEY, CLIENT_CERT, KEY_ID, clientClaims);
System.out.println("Trusted Client Signed Client Assertion:" + clientAssertion);
JsonObject userClaims = buildJWTClaims(CLIENT_ID, USER_NAME, AUDIENCE_LIST, expirationTime, now, now,
UUID.randomUUID().toString());
System.out.println(userClaims.toString());
String userAssertion = generateAndSignJWTAssertion(CLIENT_PRIVATE_KEY, CLIENT_CERT, KEY_ID, userClaims);
System.out.println("Trusted Client Signed User Assertion: " + userAssertion);
}
// Builds JsonObject with the list of claims
static JsonObject buildJWTClaims(
String issuer,
String subject,
List<String> audience,
Date expirationTime,
Date notBefore,
Date issuedAt,
String jwtId
)
{
Map<String, Object> claims = new LinkedHashMap<>();
claims.put(ISSUER_CLAIM, issuer);
claims.put(SUBJECT_CLAIM, subject);
claims.put(AUDIENCE_CLAIM, audience);
claims.put(EXPIRATION_TIME_CLAIM, expirationTime);
claims.put(NOT_BEFORE_CLAIM, notBefore);
claims.put(ISSUED_AT_CLAIM, issuedAt);
claims.put(JWT_ID_CLAIM, jwtId);
return createJsonObjectFromMap(claims);
}
public static String generateAndSignJWTAssertion(
final String base64EncodedPrivateKey,
final String base64EncodedCertificate,
final String keyID,
final JsonObject claims
) throws CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,
SignatureException
{
// Get the certificate from certificate factory
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(
new ByteArrayInputStream(Base64.getDecoder().decode(base64EncodedCertificate)));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(
new PKCS8EncodedKeySpec(Base64.getDecoder().decode(base64EncodedPrivateKey)));;
// NOTE returned Strings may be padded at end with potentially 0, 1, or 2 trailing '=' signs.
String base64X5TUrl = getCertificateDigestAsURLSafeBase64EncodedString(certificate, "SHA-1");
String base64X5T256Url = getCertificateDigestAsURLSafeBase64EncodedString(certificate, "SHA-256");
// Populate the header for signing
Map<String, Object> headers = new LinkedHashMap<>();
headers.put(ALGORITHM_HEADER, "RS256");
headers.put(KEY_ID_HEADER, keyID);
headers.put(X509CERT_SHA1_HEADER, base64X5TUrl);
headers.put(X509CERT_SHA256_HEADER, base64X5T256Url);
JsonObject header = createJsonObjectFromMap(headers);
System.out.println(header.toString());
String signingInput = toBase64URLSafe(header.toString().getBytes(StandardCharsets.UTF_8), true) + '.'
+ toBase64URLSafe(claims.toString().getBytes(StandardCharsets.UTF_8), true);
Signature signer = Signature.getInstance("SHA256withRSA");
signer.initSign(privateKey);
signer.update(signingInput.getBytes(StandardCharsets.UTF_8));
String signature = toBase64URLSafe(signer.sign(), true);
String assertion = signingInput + '.' + signature;
return assertion;
}
static JsonObject buildJWTHeader(
String issuer,
String subject,
List<String> audience,
Date expirationTime,
Date notBefore,
Date issuedAt,
String jwtId
)
{
Map<String, Object> claims = new LinkedHashMap<>();
claims.put(ISSUER_CLAIM, issuer);
claims.put(SUBJECT_CLAIM, subject);
claims.put(AUDIENCE_CLAIM, audience);
claims.put(EXPIRATION_TIME_CLAIM, expirationTime);
claims.put(NOT_BEFORE_CLAIM, notBefore);
claims.put(ISSUED_AT_CLAIM, issuedAt);
claims.put(JWT_ID_CLAIM, jwtId);
return createJsonObjectFromMap(claims);
}
private static JsonObject createJsonObjectFromMap(Map<String, Object> map)
{
JsonObjectBuilder builder = Json.createObjectBuilder();
for (Map.Entry<String, Object> claim : map.entrySet())
{
String key = claim.getKey();
Object value = claim.getValue();
if (value == null)
{
continue;
}
if (value instanceof String)
{
builder.add(key, (String) value);
}
else if (value instanceof Date)
{
builder.add(key, Long.valueOf(((Date) value).getTime() / 1000L)); // seconds since epoch
}
else if (value instanceof List)
{
List<String> list = (List<String>) value;
if (list.size() == 0)
{
continue;
}
else if (list.size() == 1)
{
String listVal = list.get(0);
if (listVal != null)
{
builder.add(key, list.get(0));
}
}
else
{
JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
for (String listVal : list)
{
if (listVal != null)
{
arrayBuilder.add(listVal);
}
}
builder.add(key, arrayBuilder);
}
}
}
return builder.build();
}
public static String getCertificateDigestAsURLSafeBase64EncodedString(
X509Certificate certificate,
String hashAlg
) throws NoSuchAlgorithmException, CertificateEncodingException
{
// hash algorithm "SHA-1" or "SHA-256"
byte[] certificateEncoded = certificate.getEncoded();
byte[] digest = MessageDigest.getInstance(hashAlg).digest(certificateEncoded);
return toBase64URLSafe(digest, true);
}
public static String toBase64URLSafe(byte[] bytes, boolean removePadding)
{
String base64URLSafeString = Base64.getUrlEncoder().encodeToString(bytes);
return removePadding
? trimTrailingBase64Padding(base64URLSafeString)
: base64URLSafeString;
}
public static String trimTrailingBase64Padding(String b64EncodedString)
{
if (b64EncodedString != null)
{
if (b64EncodedString.endsWith("=="))
{
return b64EncodedString.substring(0, b64EncodedString.length() - 2);
}
else if (b64EncodedString.endsWith("="))
{
return b64EncodedString.substring(0, b64EncodedString.length() - 1);
}
}
return b64EncodedString;
}
}
Sample Output and Decoding from Assertion Java Code
eyJhbGciOiJSUzI1NiIsImtpZCI6ImNlY3Nhc3NlcnRpb25rZXkiLCJ4NXQiOiJ4YWhmUG1xOXJqaGlya3V5YldzMXJra1oxZW8iLCJ4NXQjUzI1NiI6InFXbS12X251b3JsNDM3Nlk1LWlTY3hPd3lwVXp5bDB4Y1NsS0Nucm5xX0kifQ.eyJpc3MiOiIzMTI4MmNiZTk4NTg0MDlhYjViNWE2MDIwZTg1Y2NiNiIsInN1YiI6InNoYXVuLmxpbkBvcmFjbGUuY29tIiwiYXVkIjoiaHR0cHM6Ly9pZGVudGl0eS5vcmFjbGVjbG91ZC5jb20vIiwiZXhwIjoxNTM0NDc5ODU0LCJuYmYiOjE1MzQ0NzYyNTQsImlhdCI6MTUzNDQ3NjI1NCwianRpIjoiNmZhOWE3MGYtNTU4Yy00YzkzLWJhYzctYzZhNjcyYTA1OTkyIn0.hCTvkcA_wwSCTAM1mHa4Bib2bcdbyGBdTnJpGJ9oXqh3Tp60Jh5izwvv1Pj3GwUm1QmeAIW-GwKlwZWLuCWOEmj53FByial14E9_4_ZJGc870MGlmCTx-WzvuEMk-wWaRhtjichtYC4ofyl00qzg3Cw3WljfN-Zm4EkLJmgkjL8YflFB7qRwmFfi_X_AMjq_FSI8QPIRZqf9HOcLGLXkSqYLsDh1sEv9Og3PbGkmwRA2Zaq6waP7Izzx0ge5IfQdBIotv76IPJ0cyIVUbfhCc-TO71WqrWlfCA2dZxC7nCE0y01NBYPpaMm8kGj71lWHrIn0yfULJgYS0-lPOiAMYg
eyJhbGciOiJSUzI1NiIsImtpZCI6ImNlY3Nhc3NlcnRpb25rZXkiLCJ4NXQiOiJ4YWhmUG1xOXJqaGlya3V5YldzMXJra1oxZW8iLCJ4NXQjUzI1NiI6InFXbS12X251b3JsNDM3Nlk1LWlTY3hPd3lwVXp5bDB4Y1NsS0Nucm5xX0kifQ.eyJpc3MiOiIzMTI4MmNiZTk4NTg0MDlhYjViNWE2MDIwZTg1Y2NiNiIsInN1YiI6IjMxMjgyY2JlOTg1ODQwOWFiNWI1YTYwMjBlODVjY2I2IiwiYXVkIjoiaHR0cHM6Ly9pZGVudGl0eS5vcmFjbGVjbG91ZC5jb20vIiwiZXhwIjoxNTM0NDc5ODU0LCJuYmYiOjE1MzQ0NzYyNTQsImlhdCI6MTUzNDQ3NjI1NCwianRpIjoiYTliZGVjZGQtNWNjZS00ZjJkLTk3MTAtMjY2MWYxMGFhYmQxIn0.JvzZaeD1pS2KMrrh2CzdQk61oj04XeRXZOlMfSDDEpmaw6gSys1DrbiOWa4IPircHMRGskQ-SbGTH3IdZ_UqPgPmjDL46EpGg_1i90l-GUepnFpoUTwuUX0uDWGijrpxIF-n0DyyxipVbwVBNbduPm4vd4Gzz2r59O_0xh46DWF1KnIHyKUXiEQBwZl269ZpoFUiPPhaswOzWphYttMixUGzcsvSijPMOdPmbaSrGKXk0vBlxJqJnzQInQ_Kyj4MnP6LTHpsF3mqTnNmtnVkDy1AtShTp9xrjQGJaWLfwpswSwmBZAceMjsGIvJ3g84WJl2XcyoEEDlSR0A8z6Dyxg
| Header |
|
| Payload |
|
| Header |
|
| Payload |
|
Example Token Requests Using User Assertions
curl -i
-H 'Authorization: Basic <base64Encoded clientid:secret>'
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8'
--request POST https://<domainURL>/oauth2/v1/token
-d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=<Base64 encoded user-assertion-value>&scope=<scope value>' curl -i
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8'
--request POST https://<domainURL>/oauth2/v1/token
-d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=<Base64 encoded user-assertion-value>&scope=<scope value>' \
-d 'client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=<Base64 encoded client-assertion-value>'Token Expiry Table
The token expiry table contains the expiry setting name and provides the default value for the setting.
| Setting Name | Default Value | Description |
|---|---|---|
| Per Tenant SSO Session Expiry | Per Tenant | Per Tenant session expiry time (SSOSettings) that the tenant can modify. The default expiration is eight hours. |
| Global SSO Session Expiry | 8 Hours | Global Session expiry time (SSOConfig) |
| Request Cookie Expiry | 15 Minutes | Cookie expiry time for IDCS_REQUEST cookie |
| OAuth Access Token Expiry |
3600 Seconds Note: The default is used when a Resource App Expiry, User Session Expiry or Custom Expiry isn't set. |
An access token's (AT) expiry time is in seconds. AT expiry time is determined by a combination of the following factors:
|
| OAuth Identity Token Expiry | Set to SSO session Expiry | Set to SSO session expiry. |
| OAuth Refresh Token Expiry | 1 week | Coming from Resource Server's configuration, if available. Otherwise, it's coming from OAuthConfig for the refresh token-type expiry. If the expiry value isn't defined in OAuthConfig, the default value is one week. |
| OAuth AZ Code Expiry | 3 minutes |
Updating Refresh Token Expirations
Refresh tokens carry the information necessary to get a new access token. In other words, whenever an access token is required to access a specific resource, a client may use a refresh token to get a new access token issued by the authentication server.
A common use case is getting new access tokens after old ones have expired, such as an access token expiring on a mobile app. The mobile app sends the refresh token to obtain a new access token with no need for caching the user's password.
Refresh tokens do expire, but are typically long-lived.
The default value for the
refreshTokenExpiry attribute is seven days. The value is listed
in seconds: 604800.Get the Current Refresh Token Expiration Value
Make a GET request to the /Apps endpoint, requesting a specific App ID, and then specify the refreshTokenExpiry attribute.
Request Example
GET <domainURL>/admin/v1/Apps/{{appID}}?attributes=refreshTokenExpiry
Response Example
The refreshTokenExpiry attribute is returned in the response (in bold in the example).
{
"isAliasApp": false,
"displayName": "ResourceOwner",
"refreshTokenExpiry": 604800,
"id": "{{appID}}",
"basedOnTemplate": {
"value": "CustomWebAppTemplateId"
}
}
Alternatively, you can make a GET request to the /Apps endpoint, requesting a specific App ID to return all application-specific attributes, including the refreshTokenExpiry attribute.
Request Example
GET <domainURL>/admin/v1/Apps/{{appID}}
Response Example
The refreshTokenExpiry attribute is returned in the response (in bold in the example).
{
"accessTokenExpiry": 3600,
"clientType": "confidential",
"isAliasApp": false,
"audience": "<domainURL>",
"meta": {
"created": "2022-06-25T16:10:26.953Z",
"lastModified": "2022-06-25T20:37:14.039Z",
"resourceType": "App",
"location": "https://<domainURL>/admin/v1/Apps/9fc12da9eecd4927a9ef88512ce5612e"
},
"active": true,
"isLoginTarget": true,
"idcsCreatedBy": {
"display": "admin opc",
"type": "User",
"value": "855344f8015347e1a26c1ac9b2a2898e",
"$ref": "https://<domainURL>/admin/v1/Users/855344f8015347e1a26c1ac9b2a2898e"
},
"displayName": "ResourceOwner",
"showInMyApps": false,
"isMobileTarget": false,
"allowOffline": true,
"isUnmanagedApp": false,
"idcsLastModifiedBy": {
"display": "OAuthClient",
"type": "App",
"value": "66efab799b084c21bf84edcf1f587380",
"$ref": "https://<domainURL>/admin/v1/Apps/66efab799b084c21bf84edcf1f587380"
},
"isOPCService": false,
"refreshTokenExpiry": 604800,
"name": "3fd7476a48a94381bd5e1bc88cc92021",
"isOAuthClient": true,
"isManagedApp": false,
"isSamlServiceProvider": false,
"infrastructure": false,
"allUrlSchemesAllowed": true,
"trustScope": "Explicit",
"id": "9fc12da9eecd4927a9ef88512ce5612e",
"isWebTierPolicy": false,
"loginMechanism": "OIDC",
"allowAccessControl": false,
"isOAuthResource": true,
"migrated": false,
"isKerberosRealm": false,
"attrRenderingMetadata": [
{
"name": "aliasApps",
"visible": false
}
],
"basedOnTemplate": {
"lastModified": "2022-05-04T10:47:12Z",
"value": "CustomWebAppTemplateId",
"$ref": "https://<domainURL>/admin/v1/AppTemplates/CustomWebAppTemplateId"
},
"redirectUris": [
"http://localhost:8943"
],
"allowedGrants": [
"client_credentials",
"refresh_token",
"authorization_code"
],
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:App"
],
"clientSecret": "this-is-not-the-secret",
"grantedAppRoles": [
{
"value": "29722be952c14f9fac5237e5dd088660",
"$ref": "https://<domainURL>/admin/v1/AppRoles/29722be952c14f9fac5237e5dd088660",
"appId": "IDCSAppId",
"display": "identity domain administrator",
"type": "direct",
"appName": "IDCSApp",
"adminRole": true
},
{
"value": "6aa28be4b79143099e90e5dcdd820844",
"$ref": "https://<domainURL>/admin/v1/AppRoles/6aa28be4b79143099e90e5dcdd820844",
"appId": "IDCSAppId",
"display": "Me",
"type": "direct",
"appName": "IDCSApp",
"adminRole": true
},
{
"value": "99224c8907d84560b9621dcda9ecb8b4",
"$ref": "https://<domainURL>/admin/v1/AppRoles/99224c8907d84560b9621dcda9ecb8b4",
"appId": "IDCSAppId",
"display": "Cloud Gate",
"type": "direct",
"appName": "IDCSApp",
"adminRole": true
}
]
}
Change the Refresh Token Value
To update the refreshTokenExpiry attribute value, make a PATCH request to the /Apps endpoint specifying the App ID, and then define the updated refreshTokenExpiry attribute value in the payload.
Request Example
PATCH <domainURL>/admin/v1/Apps/{{appid}}
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
],
"Operations": [{
"op": "replace",
"path": "refreshTokenExpiry",
"value": 904800
}
]
}
Response Example
The response returned includes the updated refreshTokenExpiry attribute value (in bold in the example).
{
"accessTokenExpiry": 3600,
"clientType": "confidential",
"isAliasApp": false,
"audience": "https://<domainURL>",
"meta": {
"created": "2022-06-25T16:10:26.953Z",
"lastModified": "2022-06-25T20:37:14.039Z",
"resourceType": "App",
"location": "https://<domainURL>/admin/v1/Apps/9fc12da9eecd4927a9ef88512ce5612e"
},
"active": true,
"isLoginTarget": true,
"idcsCreatedBy": {
"display": "admin opc",
"type": "User",
"value": "855344f8015347e1a26c1ac9b2a2898e",
"$ref": "https://<domainURL>/admin/v1/Users/855344f8015347e1a26c1ac9b2a2898e"
},
"displayName": "ResourceOwner",
"showInMyApps": false,
"isMobileTarget": false,
"allowOffline": true,
"isUnmanagedApp": false,
"idcsLastModifiedBy": {
"display": "OAuthClient",
"type": "App",
"value": "66efab799b084c21bf84edcf1f587380",
"$ref": "https://<domainURL>/admin/v1/Apps/66efab799b084c21bf84edcf1f587380"
},
"isOPCService": false,
"refreshTokenExpiry": 904800,
"name": "3fd7476a48a94381bd5e1bc88cc92021",
"isOAuthClient": true,
"isManagedApp": false,
"isSamlServiceProvider": false,
"infrastructure": false,
"allUrlSchemesAllowed": true,
"trustScope": "Explicit",
"id": "9fc12da9eecd4927a9ef88512ce5612e",
"isWebTierPolicy": false,
"loginMechanism": "OIDC",
"allowAccessControl": false,
"isOAuthResource": true,
"migrated": false,
"isKerberosRealm": false,
"attrRenderingMetadata": [
{
"name": "aliasApps",
"visible": false
}
],
"basedOnTemplate": {
"lastModified": "2022-05-04T10:47:12Z",
"value": "CustomWebAppTemplateId",
"$ref": "https://<domainURL>/admin/v1/AppTemplates/CustomWebAppTemplateId"
},
"redirectUris": [
"http://localhost:8943"
],
"allowedGrants": [
"client_credentials",
"refresh_token",
"authorization_code"
],
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:App"
],
"clientSecret": "this-is-not-the-secret",
"grantedAppRoles": [
{
"value": "29722be952c14f9fac5237e5dd088660",
"$ref": "https://<domainURL>/admin/v1/AppRoles/29722be952c14f9fac5237e5dd088660",
"appId": "IDCSAppId",
"display": "identity domain administrator",
"type": "direct",
"appName": "IDCSApp",
"adminRole": true
},
{
"value": "6aa28be4b79143099e90e5dcdd820844",
"$ref": "https://<domainURL>/admin/v1/AppRoles/6aa28be4b79143099e90e5dcdd820844",
"appId": "IDCSAppId",
"display": "Me",
"type": "direct",
"appName": "IDCSApp",
"adminRole": true
},
{
"value": "99224c8907d84560b9621dcda9ecb8b4",
"$ref": "https://<domainURL>/admin/v1/AppRoles/99224c8907d84560b9621dcda9ecb8b4",
"appId": "IDCSAppId",
"display": "Cloud Gate",
"type": "direct",
"appName": "IDCSApp",
"adminRole": true
}
]
}
Using an OAuth Token for Platform Services
The OAuth 2.0 token service provided by identity domains is a mechanism that enables you to use a secured token to access the REST endpoints of Oracle Cloud Platform Services (PaaS).
-
To access a cloud platform service that's integrated with identity domains, you need the identity domain URL. If you don't know the identity domain URL, see Finding an Identity Domain URL.
-
cURL examples are used in the procedure to obtain an access token from identity domains, and then access a cloud platform service REST endpoint with the token.
An OAuth access token has an expiration value of 86,400 seconds (24 hours). To make REST API requests 24 hours after getting an access token, you need to obtain a new token.
Prerequisites
Get the following information from the identity domain before you begin.
- Identity domain URL
- Client ID
- Client secret
- Primary audience URL
- Allowed scope
-
Sign in to the My Services dashboard for your identity domain.
Note
You need to have either the identity domain administrator role or PaaS administrator role to follow the steps in this procedure. -
In the list of services, find the entry for the identity domain, and then select Identity Cloud.
-
On the Overview tab, find the Service Instances section, and then copy the value shown in the Service Instance URL field.
For example:
https://<domainURL>.identity.oraclecloud.com/ui/v1/adminconsoleWhere
<domainURL>is the REST server part of the identity domain URL (which forms part of the endpoint URL for requesting an access token). -
Select Open Service Console, expand the Navigation Drawer, and then select Applications.
-
In the search field, enter
PSMand then select the search icon. In the results, find the entry titled PSM App for API OAuth support.Note
The Platform Service Manager App (PSMApp) isn't available for Oracle Cloud accounts that were created before 18.1.4. -
Select the name of the application titled PSM App for API OAuth support. The name has the form
PSMApp-cacct-string-of-letters-and-numbers.For example:
PSMApp-cacct-9z8x7c6v5b4n3mThis is the identity domain trusted PSM client application, which is automatically created for Oracle Cloud accounts (after 18.1.4) and associated with the Oracle Cloud Platform Service.
-
Select Configuration. Under General Information, copy the value shown in the Client ID field.
This is the PSMApp client ID. For example:
PSMApp-cacct-9z8x7c6v5b4n3m_APPID -
Select Show Secret, and then copy the value.
This is the PSMApp client secret. For example:
c53b437-1768-4cb6-911e-1e6eg2g3543 -
Expand Resources. Copy the value shown in the Primary Audience field.
This is the PSMApp primary audience URL. For example:
https://psm-cacct-9z8x7c6v5b4n3m.console.oraclecloud.com -
In the Allowed Scopes section, copy the Scope value for 1PaaS Permission.
urn:opc:resource:consumer::all
Get an OAuth Access Token
With the information that you gathered, use the identity domains REST API endpoint /oauth2/v1/token to obtain a token.
curl -k
-X POST -u "client-id:client-secret"
-d "grant_type=password&username=yourusername&password=yourpassword&scope=https://primary-audience-and-scope" "https://identity-cloud-service-instance-url/oauth2/v1/token"
Where:
-
client-idis the PSMApp client ID -
client-secretis the PSMApp client secret -
yourusernameis the cloud platform service username with an administrator role -
yourpasswordis the password for the username -
primary-audience-and-scopeis a concatenation of the PSMApp primary audience URL and the 1PaaS permission scope -
identity-cloud-service-instance-urlis the REST server part of the identity domain URL
For example:
curl -k
-X POST -u "PSMApp-cacct-9z8x7c6v5b4n3m_APPID:c53b437-1768-4cb6-911e-1e6eg2g3543"
-d "grant_type=password&username=yourusername&password=yourpassword&scope=https://psm-cacct-9z8x7c6v5b4n3m.console.oraclecloud.comurn:opc:resource:consumer::all" "https://<domainURL>.identity.oraclecloud.com/oauth2/v1/token"
The following shows an example of the returned response.
{
"access_token": "eyJ7NXQ...fMf46Q0yKopDxQ",
"token_type": "Bearer",
"expires_in": 86400
}
The token string is truncated in the example response. Copy the entire token string (within the quotation marks) as shown in your response.
Use the OAuth Access Token in Cloud Platform Service REST API Requests
After you obtain an OAuth 2.0 access token, you provide the token in a bearer token header of the cloud platform service REST request.
curl -i
-X GET
-H "Authorization: Bearer token-string" "https://primary-audience/rest-endpoint-path"
Where:
-
token-stringis the OAuth access token that you obtained -
primary-audienceis the PSMApp primary audience URL -
rest-endpoint-pathis the relative path that defines the cloud platform service REST resource. Note that the identity domain ID might be used in the path.
curl -i -X GET
-H "Authorization: Bearer eyJ7NXQ...fMf46Q0yKopDxQ" "https://psm-cacct-9z8x7c6v5b4n3m.console.oraclecloud.com/paas/api/v1.1/instancemgmt/idcs-9a888b7e6ebb44b4b65/services/jaas/instances"Token Validation
Why do we validate tokens? When your web application checks credentials directly, it verifies that the username and password that are presented correspond to what you maintain. When using claims-based identity, you're outsourcing that job to an identity provider.
The responsibility shifts from verifying raw credentials to verifying that the requestor went through your preferred identity provider and successfully authenticated. The identity provider represents successful authentication by issuing a token. Before you can use the information or rely on it as an assertion that the user has authenticated, you must validate it.
OpenID Discovery Document
The OpenID Connect 1.0 protocol is a simple identity layer on top of the OAuth 2.0 protocol that requires the use of multiple endpoints for authenticating users and for requesting resources that include user information, tokens, and public keys. To help with discovering what these endpoints are that you need to use, OpenID Connect allows you to use a discovery document, which is a JSON document found at a well-known location. This discovery document contains key/value pairs that provide details about the OpenID Connect provider's configuration, including the URIs of the authorization, token, userinfo, and public keys endpoints. You can retrieve the discovery document for an IAM identity domain's OpenID Connect service from: https://<domainURL>/.well-known/openid-configuration.
See the Oracle Identity Cloud Service OpenID Discovery docs.
Validating Identity Tokens
An Identity (ID) Token is an integrity-secured, self-contained token (in JSON Web Token format) that contains claims about the end user. It represents an authenticated user's session. Therefore, the token must be validated before an application can trust the contents of the ID Token. For example, if a malicious attacker replayed a user's ID Token that they had captured earlier, the application should detect that the token has been replayed or was used after it had expired and deny the authentication.
-
Verify that the value of the audience (
aud) claim contains the application'sclient_idvalue. Theaud(audience) claim may contain an array with more than one element. The ID Token must be rejected if the ID token doesn't list the client as a valid audience, or if it contains additional audiences that aren't trusted by the client. -
Verify that the current time is before the time represented by the expiry time (
exp) claim. -
Verify that the ID Token is properly signed by the issuer. IAM identity domain-issued tokens are signed using one of the certificates found at the URI specified in the
jwks_urifield of the discovery document.-
Retrieve the tenant's public certificate from the
SigningCert/jwkendpoint (for example,https://acme.identity.oraclecloud.com/admin/v1/SigningCert/jwk).Note
Because identity domains change public keys infrequently, you can cache the public keys and, in the vast majority of cases, efficiently perform local validation. This requires retrieving and parsing certificates and making the appropriate crypto calls to check the signature: -
Use any JWT libraries available to validate, for example, Connect2id's Nimbus JWT Library for Java. See JWT for a list of available libraries.
Note
In case of signature validation failure, to prevent constant re-fetches in case of attacks with bogus tokens, the re-fetching/re-caching of the public key should be based on a time interval, such as 60 minutes, so that re-fetches only happen every 60 minutes.
Example
package sample; import java.net.MalformedURLException; import java.net.URL; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.jwk.source.RemoteJWKSet; import com.nimbusds.jose.proc.JWSKeySelector; import com.nimbusds.jose.proc.JWSVerificationKeySelector; import com.nimbusds.jose.proc.SecurityContext; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.proc.ConfigurableJWTProcessor; import com.nimbusds.jwt.proc.DefaultJWTProcessor; public class TokenValidation { public static void main(String[] args) { try { String tokenValue = "eyJ4NXQjUzI1....W9J4oQ"; ConfigurableJWTProcessor jwtProcessor = new DefaultJWTProcessor(); // change t JWKSource keySource = new RemoteJWKSet(new URL("https://<domainURL>/admin/v1/SigningCert/jwk")); // The expected JWS algorithm of the token (agreed out-of-band) JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256; // Configure the JWT processor with a key selector to feed matching public // RSA keys sourced from the JWK set URL JWSKeySelector keySelector = new JWSVerificationKeySelector(expectedJWSAlg, keySource); jwtProcessor.setJWSKeySelector(keySelector); // Process the token SecurityContext ctx = null; // optional context parameter, not required here JWTClaimsSet claimsSet = jwtProcessor.process(tokenValue, ctx); // Print out the token claims set System.out.println(claimsSet.toJSONObject()); } catch (Exception e) { e.printStackTrace(); } } } -
-
Verify that the value of the Issuer Identifier (
iss) claim exactly matches the value of theiss(issuer) claim:https://<domainURL>/
Validating Access Tokens
-
Verify that the access token is properly signed by the issuer.
-
Retrieve the tenant's public certificate from the
SigningCert/jwkendpoint (for example, https://acme.identity.oraclecloud.com/admin/v1/SigningCert/jwk).Note
Because identity domains change public keys infrequently, you can cache the public keys and, in the vast majority of cases, efficiently perform local validation. This requires retrieving and parsing certificates and making the appropriate crypto calls to check the signature: -
Use any JWT libraries available to validate, for example, Connect2id's Nimbus JWT Library for Java. See JWT for a list of available libraries.
-
Pass the certificate to the respective library's API, for example, using Nimbus SignedJWT API:
PublicKey = x509Certificate.getPublicKey(); // verify the signature. JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) (publicKey)); boolean isTokenValid = signedJWT.verify(verifier);Note
In case of signature validation failure, to prevent constant re-fetches in case of attacks with bogus tokens, the re-fetching/re-caching of the public key should be based on a time interval, such as 60 minutes, so that re-fetches only happen every 60 minutes.
-
-
Verify that the value of the Issuer Identifier (
iss) claim exactly matches the value of theiss(issuer) claim:https://<domainURL>/ -
Verify that the access token has the audience (
aud) claim as requested by the client. The value of theaudclaim changes from scope to scope. Theaudclaim is an array if there are multiple audiences and is a string if there's only one audience.The
audclaim is the primary audience of the IAM identity domain App's resource server. If there are any secondary audiences defined in the IAM identity domain App, then they're also added as part of theaudclaim. As part of the access token validation, the server must allow access if one of the values in theaudarray makes sense to the resource server. -
Verify that the current time is before the time represented by the expiry time (
exp) claim. -
Verify that the access token is authorized to perform the operation based on the contents of the scope claim. The scope claim in the access token is a space-separated list of strings.
Working with AppRoles
Learn about AppRole permissions, which AppRoles can be granted to clients and users, and how to grant app roles to apps and groups.
AppRoles That Can Be Granted to Clients and Users
Identity domains application roles define what a user or application client can do in an identity domain. These AppRoles directly translate into identity domain OAuth scopes that are used to secure access to protected identity domain resources. Some AppRoles are available only to clients. Some AppRoles are available to both clients and users.
AppRoles Granted Only to Clients
-
Authenticator Client
-
Change Password
-
Cloud Gate
-
DB administrator
-
Forgot Password
-
Kerberos Authenticator
-
Me
-
MFA Client
-
Reset Password
-
Self Registration
-
Signin
-
Verify Email
AppRoles Granted to Clients and Users
-
Authenticator Client
-
Change Password
-
Cloud Gate
-
DB administrator
-
Forgot Password
-
Kerberos administrator
-
Me
-
MFA Client
-
Reset Password
-
Self Registration
-
Signin
-
Verify Email
Granting AppRoles to Groups
Use the following example to create a request that grants application roles to an a group.
{
"app": {
"value": "<app_id>"
},
"entitlement": {
"attributeName": "appRoles",
"attributeValue": "<appRoles_id>"
},
"grantMechanism": "ADMINISTRATOR_TO_GROUP",
"grantee": {
"value": "<grantee_id>",
"type": "Group"
},
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:Grant"
]
}
Authentication and On-Demand MFA API HTTP Status Codes
The Authentication and On-Demand Multifactor Authentication (MFA) APIs for identity domains in IAM are REST compliant and use standard HTTP response status codes to indicate failure.
This table describes the different status codes and the use cases in which these status codes are sent.
See the Status Code Definitions section of the Hypertext Transfer Protocol -- HTTP/1.1.
|
HTTP Status Code |
Use Case |
Sample JSON Response Body |
|---|---|---|
400 Bad Request
|
This code indicates a bad request. This code is sent if any attribute is supplied with an invalid value in the payload, which signifies syntax issues. |
|
401 Unauthorized
|
This code indicates unauthorized access. This is used when the
|
|
422
|
This code is used when the request is syntactically correct, but semantically wrong. 422 means that the request is an unprocessable entity. For example, when the request is missing the |
|
500 Internal Server Error
|
This code indicates an internal server error. When this error
occurs, the response contains the |
Authentication and On-Demand MFA API Error Codes
The Authentication and On-Demand Multifactor Authentication (MFA) APIs for identity domains in IAM provide error codes and descriptive messages when errors occur.
This table lists the authentication error codes that the Authentication and On-Demand MFA APIs respond with when errors occur.
|
Error Code |
Error Message |
|---|---|
AUTH-3001
|
You entered an incorrect username or password. |
AUTH-3002
|
Your account is locked. Contact your system administrator. |
AUTH-3003
|
Your account is deactivated. Contact your system administrator. |
AUTH-3004
|
Your password is expired. |
AUTH-3005
|
You must change your password. |
AUTH-3006
|
A system error has occurred in identity domains. Contact your system administrator. |
AUTH-3007
|
The username that you entered is invalid. Contact your system administrator. |
AUTH-3008
|
Invalid token. Contact your system administrator. |
AUTH-3009
|
Token expired. Contact your system administrator. |
AUTH-3010
|
Identity domains can't authenticate the user account. Contact your system administrator. |
AUTH-3011
|
There's a problem with the identity domains server. Contact your system administrator. |
AUTH-3012
|
A federated user can't perform local authentication. |
AUTH-3013
|
The logout URL {0} is invalid. |
AUTH-3014
|
Token has no subject. |
AUTH-3015
|
Token has no issuer. |
AUTH-3016
|
Token has invalid issue time. |
AUTH-3017
|
Token has no expiry time. |
AUTH-3018
|
User not found. |
AUTH-3019
|
Token has no issue time. |
AUTH-3020
|
The Subject claim doesn't match the Issuer claim. |
AUTH-3021
|
The Identity Provider name is either blank or incorrect in the request. |
AUTH-3022
|
No identity provider is configured. |
AUTH-3023
|
The credentials that you entered don't match the existing user session. |
AUTH-3024
|
You aren't authorized to access the app. Contact your system administrator. |
AUTH-3025
|
Your account isn't activated. To activate your account, select the link in the activation email that was sent to your email address. |
AUTH-3026
|
Invalid login request. The request wasn't initiated using a supported protocol channel. |
AUTH-3028
|
Identity domains can't authenticate the user account. Contact your system administrator. |
AUTH-3029
|
MFA is enabled for the user. The user must provide a second factor of authentication in addition to password authentication. |
AUTH-3030
|
Tenant has Multifactor Authentication (MFA) enabled. Use MFA for all users of this tenant. |
AUTH-3031
|
User has Multifactor Authentication (MFA) enabled. Use MFA for this user. |
AUTH-3032
|
The user is already logged in. |
AUTH-3033
|
The sign-on policy prevents the user {0} from accessing applications protected by identity domains because: {1}. |
AUTH-3034
|
You configured an invalid error URL. |
AUTH-1001
|
Invalid request. The required parameter '{0}' is missing from the request. |
AUTH-1002
|
The {0} authentication factor is not supported or enabled. |
AUTH-1003
|
Your request to enroll failed because: {0}. Contact your system administrator. |
AUTH-1004
|
Enrollment initiation request failed because: {0}. |
AUTH-1005
|
You are enrolled in the maximum number of 2-Step Verification methods that are allowed. |
AUTH-1006
|
Authentication initiation request failed because {0}. |
AUTH-1007
|
Authentication failed. |
AUTH-1008
|
Couldn't validate security questions because: {0}. |
AUTH-1009
|
Couldn't update security questions because: {0}. |
AUTH-1010
|
Your account is locked. Contact your system administrator. |
AUTH-1011
|
No MFA factors are enabled for this domain. |
AUTH-1012
|
System error. |
AUTH-1013
|
You are not authorized to use 2-Step Verification. Contact your system administrator. |
AUTH-1014
|
The device with ID {1} is not found. Contact your system administrator. |
AUTH-1015
|
User has not selected any security questions. |
AUTH-1016
|
You can't skip enrollment. 2-Step Verification is required. |
AUTH-1017
|
Your 2-Step Verification methods are no longer valid. Contact your system administrator. |
AUTH-1018
|
The ""{0}"" security question hasn't been enabled for user enrollment. Please contact your system administrator. |
AUTH-1020
|
You've already provided this answer for another security question. Please specify a different answer for this question. |
AUTH-1021
|
The answer to the ""{0}"" security question must have at least {1} characters. |
AUTH-1022
|
You must set up {0} security questions to use the Security Questions feature. |
AUTH-1023
|
The hint can't be the same as the answer of a security question. |
AUTH-1024
|
You can select a security question only once. |
AUTH-1026
|
You have entered the wrong answer. |
AUTH-1027
|
You have exceeded the maximum number of 2-Step Verification attempts. Reset your password to unlock your account. Contact your system administrator if you can't reset your password. |
AUTH-1028
|
You have exceeded the maximum number of 2-Step Verification attempts. Contact your system administrator to unlock your account. |
AUTH-1029
|
Resetting factors cannot be supported if enrollment type is Required. |
AUTH-1030
|
Your phone number {0} is not valid. |
AUTH-1031
|
The phone number {0} is already enrolled for the user. |
AUTH-1032
|
The device status is not valid. |
AUTH-1033
|
Payload error. Either the payload in the request is null, or the payload couldn't be parsed. |
AUTH-1034
|
You are not authorized to perform this action. |
AUTH-1035
|
You have already enrolled in 2-Step Verification. Register for additional factors using the administrative console. |
AUTH-1036
|
Session is no longer valid. Close the browser and log in again. |
AUTH-1037
|
You must set {0} security questions. |
AUTH-1038
|
Please provide your answer for the ""{0}"" security question. |
AUTH-1039
|
The ID of the {0} security question isn't valid. |
AUTH-1040
|
You must answer {0} security questions. |
AUTH-1041
|
Your answer to the ""{0}"" security question can't exceed {1} characters. |
AUTH-1042
|
Your hint to the ""{0}"" security question can't exceed {1} characters. |
AUTH-1100
|
The SMS authentication factor is not enabled. |
AUTH-1101
|
The PUSH authentication factor is not enabled. |
AUTH-1102
|
The OTP authentication factor is not enabled. |
AUTH-1103
|
The Security Questions authentication factor is not enabled. |
AUTH-1104
|
The Bypass Code authentication factor is not enabled. |
AUTH-1105
|
Invalid passcode. |
AUTH-1106
|
Unable to process the request at this time. Use a backup verification method. |
AUTH-1107
|
Pull notification channel has not been enabled for your tenant. |
AUTH-1108
|
Push Notification approval is pending. |
AUTH-1109
|
Enrollment in the One-Time Passcode authentication method is pending verification. |
AUTH-1110
|
The authentication token has expired. |
AUTH-1111
|
The request provided is invalid. Please look at the error message for validation error details. |
AUTH-1112
|
Unexpected error encountered while processing the request. |
AUTH-1113
|
An authentication factor must be provided while configuring a preferred device. |
AUTH-1114
|
You must provide the deviceId when configuring {0} as the preferred authentication factor. |
AUTH-1115
|
The authentication factor passed in the request is not supported. Supported factors are {0}. |
AUTH-1116
|
The op passed in the request is not supported. Supported operations are {0}. |
AUTH-1117
|
The requestState provided has expired. Please provide a valid requestState. |
AUTH-1118
|
You provided an invalid appName. Verify that the App display name is correct. |
AUTH-1119
|
The operation {0} isn't supported by the {1} endpoint. Use the {2} endpoint. |
AUTH-1120
|
The requestState provided is either invalid or expired. Please provide a valid requestState. |
AUTH-1121
|
You provided an invalid request JSON payload. |
AUTH-1122
|
The application is not active. |
AUTH-1123
|
An error occurred while logging in using social identity. |
API Use Cases
Step through typical use cases using the IAM identity domain REST APIs.
The response output that you get might differ from the response examples shown in the use cases. The output depends on the release and environment, and the configuration of the identity domain.
| Task | More Information |
|---|---|
|
Adaptive Risk Analysis for Custom Client Applications |
This use case provides an example request of using the adaptive risk analysis endpoints for custom applications and on-premises access management systems. |
|
Oracle Services Onboarding Using the API |
Identity domain administrators can manage the onboarding process of OPC applications to an identity domain. |
|
Changing Your Own Profile Attributes |
Use the API to change your own profile attributes (for example, an email address or a password) by setting the |
|
Creating an Enterprise Application with Authorization Policy |
This use case provides an example request of creating an enterprise application using REST API. See Creating an Enterprise Application with Authorization Policy. |
|
Importing and Exporting Users, Groups, and AppRoles |
These use cases provide example requests for bulk loading users, groups, and application roles from other repositories into an identity domain. |
|
Managing Custom Claims |
This use case provides an example request of how to add custom claims to an access token, an identity token, or both the tokens. |
|
Managing the Refresh Token Expiration Value |
This use case provides an example of how to verify the validity of a refresh token and update the token expiry time. |
|
Managing User Schema Customizations |
This use case provides examples of how to add, update, remove, and enable the import of custom user schema attributes in an identity domain. |
|
Obtaining and Using an OAuth Token for Platform Services |
This use case provides an example request of how to use a OAuth 2.0 token issued by an identity domain to access REST endpoints from an Oracle Cloud Platform Services (PaaS). |
|
Triggering an Email Verification Flow if Email Address is Already Verified |
This use case provides an example of how custom clients can re the change email flow for users who already have verified their email addresses. Resending Email Verifications When The Email Address Is Already Verified |
|
Using Duo Security with an IAM identity domain |
This use case provides an example of how to use an Authenticate API with Duo Security. |
|
Using OpenID Connect to Extend OAuth 2.0 |
This use case provides an example of how client applications can authenticate to an identity domain using OpenID connect protocol and identity domain REST APIs. |
|
Using Self Service to Enroll in MFA using the SMS Factor |
This use case provides a step-by-step example of using the identity domain REST API for Self-Service enrollment in Multifactor Authentication (MFA) using SMS Factor. See Enrolling in MFA using the SMS Factor Using Self Service. |
|
Using the Authenticate API to develop a custom sign-in page |
This use case provides an example of how to use the Authenticate API to develop a custom sign-in page. |
|
Using the Audit Event APIs |
This use case provides example of how to get Audit logs covering significant events, changes, and actions. Important: IAM identity domains AuditEvents and certain reports templates in the Reports APIs will stop returning new data after May 15, 2024. Instead, you can use the OCI Audit service to get this data. To view service change announcements for IAM, see IAM Service Change Announcements. |
|
Using the |
This use case provides an example of how to create an application and specify the |
|
Using the On Demand MFA API to Develop Custom Sign-In Page |
This use case provides a step-by-step example of using the Authenticate API to authenticate users and perform multifactor enrollment and authentication. This is used when you develop a custom sign-in page. See Using the On-Demand MFA API to Develop Custom Sign-In Page. |
|
Working with Apps |
These use cases provide example requests to create and activate an OAuth Resource Server, an OAuth Client Apps, and a SAML App using the REST APIs. Each use case also provides the required App attributes. See Working with Apps. |
|
Working with OAuth 2 to Access the REST API |
This use case walks you through using an OAuth client with identity domains to access the REST APIs. |
Using OAuth 2 to Access the REST API
The identity domains REST API supports SCIM 2.0 compliant endpoints with standard SCIM 2.0 core schemas and Oracle schema extensions to programmatically manage users, groups, applications, and identity functions, such as password management and administrative tasks. To make REST API calls to your identity domain, you need an OAuth2 access token to use for authorization. The access token provides a session (with scope and expiration), that your client application can use to perform tasks in an identity domain.
The following sequence diagram illustrates a basic example of the OAuth 2.0 authorization flow to access the identity domains REST API.
Use specific OAuth 2.0 parameters when working with an identity domain. The following table describes the most common parameters.
| Parameter | Value | Comments |
|---|---|---|
|
Authorization Header |
Basic <base64_clientid_secret> |
Used by the client as a Basic authentication scheme to transmit the access token in a header. The access token value needs to be a base64 UTF-8 encoded value of the Client ID and Client Secret concatenated using a colon as a separator-for example, clientID:clientSecret. |
|
Client ID |
<client_id> |
Required. A unique "API Key" that's generated when you register your application in the identity domain Console. |
|
Client Secret |
<client_secret> |
Required. A private key similar to a password that's generated when you register your application in the identity domain Console. Don't share this value. |
|
Access Token URL |
/oauth2/v1/token |
An endpoint used to obtain an access token from the identity domain. |
|
Auth URL |
/oauth2/v1/authorize |
An endpoint used to obtain an authorization code from identity domains, and then used during a 3-legged OAuth flow. |
|
Grant Type |
client_credentials |
Required. It means the REST API that's invoked is owned by the client application. |
|
Scope (required) |
urn:opc:idm:__myscopes__ |
This scope returns all the grants given to your application, other scopes could be used to get specific grants, if necessary. |
Step 1: Register a Confidential Application in Identity Domains Using the Console
When you register a confidential application in the identity domain Console, you obtain some of the key parameters that you need to work with OAuth 2.0: Client ID, Client Secret, and Scopes. OAuth 2.0 is a standard for implementing delegated authorization, and authorization is based on the access token required to access a resource. The access token can be issued for a given scope, which defines what the access token can do and what resources it can access. When you register a web application in an identity domain, you add scopes. In the following example, the required scopes to request User searches, edits, creates, and deletes are added. But, if you were to do other things-for example, manage Audit Events, that would require other scopes.
To create and register a confidential application access the OCI Console and then complete the following steps:
- Open the navigation menu and select Identity & Security. Under Identity, select Domains.
- Click the name of the identity domain that you want to work in. You might need to change the compartment to find the domain that you want. Then, click Integrated applications.
- Select Add application.
- In the Add application dialog box, select Confidential Application, and then select Launch workflow.
- On the Add application details page, enter an application name and description, and then select Next.
- On the Configure OAuth page, under Client configuration, select Configure this application as a client now.
- Under Authorization, select only Client Credentials as the Allowed Grant Type.
- At the bottom of the page, select Add app roles and then select Add roles.
- In the Add app roles panel, select Identity Domain Administrator, and then select Add.
- Select Next and then select Finish.
- On the application detail page, scroll down to General Information. Copy the Client ID and the Client Secret and store it in a safe place.
- After the application is created, select Activate.
Step 2: Base64 Encode the Client ID and Client Secret
Before base64 encoding, individually URL encode the client ID and the client secret. If your client ID and client secret don't contain special characters, you aren't required to URL encode them first. However, as a best practice, we highly recommend it.
Windows
-
Launch Notepad, and then paste the client ID and client secret into Notepad.
-
Place the client ID and client secret on the same line and insert a colon between them:
clientid:clientsecretNote
Ensure that no spaces are the clientid:clientsecret attribute. -
Save the file to
C:\tempand name the fileappCreds.txt. -
In Windows Explorer, right-click
C:\temp, and then select CMD Prompt Here from the context menu. -
Enter the following command to encode the client ID and client secret:
certutil -encode appCreds.txt appbase64Creds.txt -
In Notepad, open
C:\temp\appbase64Creds.txt, copy its contents, and then close the file.Note
For security reasons, delete theappCreds.txtand theappbase64Creds.txtfiles after you finish.
Mac and Linux
-
Launch your preferred note utility (for example, Mac Notes, Gedit Linux, or Vi), and then paste the client ID and client secret into the note utility.
Place the client ID and client secret on the same line and insert a colon between them:
clientid:clientsecret.Notestatement.
Ensure no spaces in the clientid:clientsecret.-
Copy the
clientid:clientsecretline. -
Launch a terminal and enter the following command, replacing
clientid:clientsecretwith the value that you copied to the clipboard.echo -n "clientid:clientsecret" | base64 -w 0Note
For Linux, add-w 0to the command to remove line breaks. -
Copy the value that's returned.Note
If the value that's returned is broken into more than one line, return to your text editor and ensure the entire results are on a single line with no text wrapping.
Step 3: Obtain an Access Token
The next step in this process is to request the access token.
-
Launch a command prompt.
-
Enter the cURL command below, replacing the text in brackets ( < > ) with the appropriate values:
curl -i -H "Authorization: Basic <base64encoded clientid:secret>" -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" --request POST https://<domainURL>/oauth2/v1/token -d "grant_type=client_credentials&scope=urn:opc:idm:__myscopes__"Note
If you're using a UNIX OS, you can append| awk -F"\"" '{print $4}'to the end of the cURL command to parse out just the Bearer token. Just remember that the default expiration of the token is 3600 seconds from the time of the request.Note
Optionally, run the following cURL command to have the access token value accessible through a UNIX variable calledAccessTokenValuein your environment:
You can then runexport AccessTokenValue=`curl -i -H "Authorization: Basic <base64encoded clientid:secret>" -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" --request POST https://<domainURL>/oauth2/v1/token -d "grant_type=client_credentials&scope=urn:opc:idm:__myscopes__" | awk -F"\"" '{print $4}' | tail -n +16`echo $AccessTokenValuecommand to get the access token value.Text in Brackets Value base64encoded clientid:secret Replace with the encoded credentials that you generated in the Base64 Encode the client ID and client secret section. Ensure no spaces in the clientid:clientsecret credentials. IDCS_Service_Instance Replace with your identity domain URL (for example, https://<domainURL>/).Note
Theurn:opc:idm:__myscopes__scope in the command is used as a tag by identity domain clients requesting access tokens from the OAuth authorization server. Access tokens are returned that contain all applicable identity domains scopes based on the privileges represented by the identity domains administrator roles granted to the requesting client and the user being specified by the client's request (if present). This scope isn't granted directly to any identity domains administrator role. -
Copy the
access_tokenvalue from the response. Ensure to copy only the actual token, which is theaccess_tokenvalue between the quotation marks:Status: 200 "access_token":"eyJ4NXQiOiI4Wk. . ." "token":"Bearer", "expires_in":3600Note
The response includes theexpires_in: 3600parameter. This means that your token is no longer valid after one hour from the time that you generate it. After one hour, you must refresh the token or get a new access token. To refresh the token, enter the cURL command below, replacing the text in brackets ( < > ) with the appropriate values:curl -i -H "Authorization: Basic <base64 encoded client ID and secret>" -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" --request POST https://<domainURL>/oauth2/v1/token -d "grant_type=refresh_token&refresh_token=<token_value>"
Step 4: Make a REST Request to the Environment
After you obtain the OAuth 2.0 access token, you can use the token in a cURL command to send a REST request to the identity domains REST API. The following command returns a list of users in an identity domain.
curl -X GET
-H "Content-Type:application/scim+json"
-H "Authorization: Bearer <access_token>"
https://<domainURL>/admin/v1/Users
| Item | Value |
|---|---|
| Method | -X GET |
| Content Type Header | -H "Content-Type:application/scim-json" |
| Authorization Header | -H "Authorization: Bearer <access_token>" |
| HTTP Protocol | HTTP or HTTPS (HTTP is recommended) |
| Identity Domain | The identity domain URL (for example, https://<domainURL>). |
| Identity Domains REST Endpoint | /admin/v1/Users |
Example JSON Output from the Identity Domains REST API
In the previous step, the REST request sent using cURL returned a response in JSON format. JSON is an open standard that can be formatted or parsed per your needs such as getting specific attributes required by your application.
{
"schemas": [
"urn:scim:api:messages:2.0:ListResponse"
],
"totalResults": 1,
"Resources": [
{
"displayName": "admin opc",
"name": {
"givenName": "admin",
"formatted": "admin opc",
"familyName": "opc"
},
"urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User": {
"locked": {
"on": false
}
},
"userName": "admin@example.com",
"id": "d252a54d83c344eb8f59f7053a0562ce",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:user:User": {
"isFederatedUser": false
},
"active": true,
"nickName": "TAS_TENANT_ADMIN_USER",
"emails": [
{
"verified": false,
"value": "admin@example.com",
"type": "work",
"primary": true
},
{
"verified": false,
"value": "admin@example.com",
"primary": false,
"type": "recovery"
}
],
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:extension:user:User",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User",
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"meta": {
"resourceType": "User",
"created": "2022-07-22T18:11:08Z",
"lastModified": "2022-07-25T21:19:28Z",
"location": "https://<domainURL>admin/v1/Users/d252a54d83c344eb8f59f7053a0562ce"
},
"idcsLastModifiedBy": {
"value": "idcssso",
"$ref": "https://<domainURL>admin/v1/Apps/idcssso",
"type": "App",
"display": "idcssso"
}
}
],
"startIndex": 1,
"itemsPerPage": 50
}
Adaptive Risk Analysis for Custom Client Applications
Customers moving to the Cloud can leverage IAM identity domain adaptive capabilities to meet risk-based analysis for their on-premises access management system, such as Oracle Access Manager (OAM), or client applications.
Identity domains provide an adaptive REST API interface to enable these on-premises access management systems or client applications to use an identity domain risk-based engine to evaluate authentication activities for users.
For example, John Doe is a user in the OAM identity store and in an identity domain. John accesses a finance application protected by OAM. The OAM server redirects him to the OAM sign-in page for authentication. John Doe submits his credentials and based on the risk score returned by the identity domain adaptive risk-based engine, the OAM server may challenge the user with a second factor. If the risk score is high, then OAM may deny access to John and present him a message indicating his attempt to sign in failed.
-
Populate Risk:
/admin/v1/sdk/adaptive/PopulateRisks -
Fetch Risk Info:
/admin/v1/sdk/adaptive/FetchRisks -
Mitigate Risk:
/admin/v1/sdk/adaptive/MitigateRisks
The adaptive REST API interface requires the client application to send information such as user identification, information of the device the user uses to sign in, and client's true IP address.
To gather device information that your access management system needs to use a device fingerprint JavaScript file. You can download the device fingerprint JavaScript file from the identity domain console.
- Sign in to identity domain Console as an application administrator.
- Expand the Navigation Drawer, select Settings, and then select Downloads.
- In the Downloads page, download the Identity Cloud Service Device Fingerprint Utility.
The file you download is a compressed (zip) file. Inside the zip file there's a JavaScript file that the access management system sign-in page or the client application itself needs to load to collect fingerprint information. Then use the getFingerprint() function to collect user's device fingerprint to send to the identity domains adaptive REST API interface.
See also Enable the Access for an unknown device Event for a Custom Sign-In Page.
Populate Risk
This endpoint is used to submit risk data to an identity domain to increase the user's risk score.
curl -k -X POST 'https://<domainURL>/admin/v1/sdk/adaptive/PopulateRisks'
-H 'Authorization: Bearer <Access_Token>'
-H 'Accept:application/json'
-d '<Request_Body>'{
"userName": "<User_Name>",
"data": [
{
"name": "device",
"value": "<result_of_the_devicefingerprint_javascript_file>"
},
{
"name": "client-ip",
"value": "<ip_address_of_the_user_browser>"
}
],
"event": "MAX_PASSWORD_FAILED_ATTEMPTS"
}The event attribute is optional. If not present in the request then
all risk events are going to be used to evaluate risk score. You can use
MAX_MFA_FAILED_ATTEMPTS or
MAX_PASSWORD_FAILED_ATTEMPTS values.
10.11.12.13. The device fingerprint and IP address will be validated against all enabled risk events in an identity domain. curl -k -X POST https://<domainURL>/v1/sdk/adaptive/PopulateRisks \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <Access_Token>' \
-d '{
"userName": "johndoe@example.com",
"data": [
{
"name": "device",
"value": "{\"currentTime\":\"Wed Nov 13 2019 16:57:34 GMT-0700 (Pacific Daylight Time)\",\"screenWidth\":1920,\"screenHeight\":1080,\"screenColorDepth\":24,\"screenPixelDepth\":24,\"windowPixelRatio\":1,\"language\":\"en-US\",\"userAgent\":\"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0\"}"
},
{
"name": "client-ip",
"value": "10.11.12.13"
}
]
}'{
"userName": "johndoe@example.com",
"riskLevel": "LOW",
"riskScores": [
{
"lastUpdateTimestamp": "2022-11-12T10:41:57.997Z",
"score": 15,
"riskLevel": "LOW",
"value": "ORACLE_IDCS",
"status": "ACTIVE",
"source": "Default Risk Provider",
"$ref": "https://<domainURL>/admin/v1/RiskProviderProfiles/ORACLE_IDCS"
}
]
}Fetch Risk Info
This endpoint enables clients to get current risk information for a single user, multiple users, or for all users in an identity domain.
curl -k -X POST 'https://<domainURL>/admin/v1/sdk/adaptive/FetchRisks' -H 'Authorization: Bearer <Access_Token>' -H 'Accept:application/json' -d '<Request_Body>'
{
"userNames": [
"<user_name>"
]
}{
"userNames": [
"<user_name_1>",
"<user_name_2>"
]
}{} curl -k -X POST https://<domainURL>/admin/v1/sdk/adaptive/FetchRisks \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer <Access_Token>' \
-d '{
"userNames": [
"johndoe@example.com"
]
}'{
"totalResults": 1,
"resources": [
{
"userName": "johndoe@example.com",
"riskLevel": "LOW",
"riskScores": [
{
"lastUpdateTimestamp": "2022-11-13T18:41:57.997Z",
"score": 15,
"riskLevel": "LOW",
"value": "ORACLE_IDCS",
"status": "ACTIVE",
"source": "Default Risk Provider",
"$ref": "https://<domainURL>/admin/v1/RiskProviderProfiles/ORACLE_IDCS"
}
]
}
],
"startIndex": 1,
"itemsPerPage": 50
}Mitigate Risk
This endpoint enables client applications to request mitigation of a user's risk score because the user has logged in or reset their password successfully.
curl -k
-X POST 'https://<domainURL>/admin/v1/sdk/adaptive/MitigateRisks'
-H 'Authorization: Bearer <Access_Token>'
-H 'Accept:application/json'
-d '<Request_Body>'{
"userName": "<User_Name>",
"data": [
{
"name": "device",
"value": "<result_of_the_devicefingerprint_javascript_file>"
},
{
"name": "client-ip",
"value": "<ip_address_of_the_user_browser>"
}
],
"event": "SSO_THREAT_MITIGATION_SUCCESS"
}event attribute of the request body can receive multiple
values:- For successful user sign-in, provide
SSO_THREAT_MITIGATION_SUCCESS. - For successful user password reset, provide
ADMIN_ME_PASSWORD_CHANGE_SUCCESS.
10.11.12.13. curl -X POST \
https://<domainURL>/admin/v1/sdk/adaptive/MitigateRisks \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <Access_Token>' \
-d '{
"userName": "johndoe@example.com",
"data": [
{
"name": "device",
"value": "{\"currentTime\":\"Thu Nov 14 2019 10:11:18 GMT-0700 (Pacific Daylight Time)\",\"screenWidth\":1440,\"screenHeight\":900,\"screenColorDepth\":24,\"screenPixelDepth\":24,\"windowPixelRatio\":2,\"language\":\"en-US\",\"userAgent\":\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36\"}"
},
{
"name": "client-ip",
"value": "10.11.12.13"
}
],
"event": "SSO_THREAT_MITIGATION_SUCCESS"
}'{
"userName": "johndoe@example.com",
"riskLevel": "LOW",
"riskScores": [
{
"lastUpdateTimestamp": 1574726401582,
"score": 10,
"riskLevel": "LOW",
"providerId": "ORACLE_IDCS",
"providerStatus": "ACTIVE",
"providerDescription": "Default Risk Provider",
"reference": "https://<domainURL>/admin/v1/RiskProviderProfiles/ORACLE_IDCS"
}
]
}Using allowSelfChange To Update Profile Attributes
You can use the API to change your own profile attributes (for example, an email address or a password) in an identity domain by setting the allowSelfChange attribute to true in the request payload or URL query string parameter. By default, this attribute is set to false.
Use the allowSelfChange attribute in the request payload for the following operations:
- Users (PATCH, REPLACE)
- UserCapabilityChanger (REPLACE)
- UserLockedStateChanger (CREATE)
- UserPasswordChanger (REPLACE)
- UserPasswordResetter (REPLACE)
- UserStateChanger (PATCH)
- UserStatusChanger (REPLACE)
- UserDbCredentials (CREATE)
- ApiKeys (CREATE, UPDATE)
- AuthTokens (CREATE, UPDATE)
- CustomerSecretKeys (CREATE, UPDATE)
- OAuth2ClientCredentials (CREATE, UPDATE)
- SmtpCredentials (CREATE, UPDATE)
- SupportAccounts (CREATE)
allowSelfChange attribute as a URL query string parameter for the DELETE operation on the following APIs. You must set
allowSelfChange=true as a URL query string parameter for DELETE operations. - UserDbCredentials
- ApiKeys
- AuthTokens
- CustomerSecretKeys
- OAuth2ClientCredentials
- SmtpCredentials
- SupportAccounts
Sample Request: /Users
/admin/v1/Users/<id>{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
],
"Operations": [
{
"op": "replace",
"path": "phoneNumbers",
"value": [
{
"type": "home",
"value": "555-555-0100"
}
]
},
{
"op": "add",
"path": "urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange",
"value": true
}
]
}Sample Request: /UserCapabilitiesChanger
/admin/v1/UserCapabilitiesChanger/<id>{
"canUseApiKeys": true,
"canUseAuthTokens": false,
"canUseConsolePassword": true,
"canUseCustomerSecretKeys": true,
"canUseOAuth2ClientCredentials": true,
"canUseSmtpCredentials": true,
"canUseDbCredentials": true,
"urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange": true,
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:UserCapabilitiesChanger"
]
}Sample Request: /UserLockedStateChanger
/admin/v1/UserLockedStateChanger{
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:UserLockedStateChanger"
],
"userId": "<unique_ID>",
"locked": false,
"urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange": true
}Sample Request: /UserPasswordChanger
/admin/v1/UserPasswordChanger{
"password": "example-password",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange": true,
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:UserPasswordChanger"
]
}
Sample Request: /UserPasswordResetter
/admin/v1/UserPasswordResetter{
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:UserPasswordResetter"
],
"urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange": true
}
Sample Request: /UserStatusChanger
/admin/v1/UserStatusChanger{
"active": true,
"urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange": true,
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:UserStatusChanger"
]
}
Sample Requests: /ApiKeys
/admin/v1/ApiKeys{
"user": {
"value": "<unique_ID>"
},
"key": "-----BEGIN PUBLIC KEY-----<your_public_key>
-----END PUBLIC KEY-----",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange": true,
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:apikey"
]
}
/admin/v1/ApiKeys/<id>{
"Operations": [
{
"op": "replace",
"path": "description",
"value": "<updated_api_key>"
},
{
"op": "add",
"path": "urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange",
"value": true
}
],
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
]
}
/admin/v1/ApiKeys/e1eaf8a28e58485fb86f16f914fd08c7?allowSelfChange=trueSample Requests: /SmtpCredentials
/admin/v1/SmtpCredentials/<id>{
"description": "John's smtp credential",
"user": {
"value": "<unique_ID>"
},
"urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange": true,
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:smtpCredential"
]
}
/admin/v1/SmtpCredentials{
"Operations": [
{
"op": "replace",
"path": "description",
"value": "updated_credential_description"
},
{
"op": "add",
"path": "urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange",
"value": true
}
],
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
]
}
Operation: DELETE /admin/v1/SmtpCredentials/e1eaf8a28e58485fb86f16f914fd08c7?allowSelfChange=true
Sample Requests: /AuthTokens
/admin/v1/AuthTokens{
"description": "John's auth token",
"user": {
"value": "<unique_ID>"
},
"urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange": true,
"schemas": ["urn:ietf:params:scim:schemas:oracle:idcs:authToken"]
}
/admin/v1/AuthTokens/<id>{
"Operations": [
{
"op": "replace",
"path": "description",
"value": "<updated_credential_description>"
},
{
"op": "add",
"path": "urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange",
"value": true
}
],
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
]
}
Operation: DELETE /admin/v1/SmtpCredentials/e1eaf8a28e58485fb86f16f914fd08c7?allowSelfChange=true
Sample Requests: /CustomerSecretKeys
/admin/v1/CustomerSecretKeys{
"diplayName": "Alice Customer Secret Key",
"description": "Alice's Customer Secret Key",
"user": {
"value": "<unique_ID>"
},
"urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange": true,
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:customerSecretKey"
]
}
/admin/v1/CustomerSecretKeys/<id>{
"Operations": [
{
"op": "replace",
"path": "description",
"value": "<updated_credential_description>"
},
{
"op": "add",
"path": "urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange",
"value": true
}
],
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
]
}
Operation: DELETE /admin/v1/CustomerSecretKeys/e1eaf8a28e58485fb86f16f914fd08c7?allowSelfChange=true
Sample Requests: /OAuth2ClientCredentials
/admin/v1/OAuth2ClientCredentials{
"name": "User's oauth2 client credential",
"scopes": [
{
"audience": "urn:opc:idm",
"scope": "__myscopes__"
}
],
"user": {
"value": "<unique_ID>"
},
"urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange": true,
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:oauth2ClientCredential"
]
}
/admin/v1/OAuth2ClientCredentials/<id>{
"Operations": [
{
"op": "replace",
"path": "description",
"value": "<updated_credential_description>"
},
{
"op": "add",
"path": "urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange",
"value": true
}
],
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
]
}
Operation: DELETE /admin/v1/OAuth2ClientCredentials/e1eaf8a28e58485fb86f16f914fd08c7?allowSelfChange=true
Sample Request: /SupportAccounts
/admin/v1/SupportAccounts{
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:supportAccount"
],
"token": "dummy",
"user": {
"ocid": "ocid1.user.region1..<unique_ID>"
},
"urn:ietf:params:scim:schemas:oracle:idcs:extension:selfChange:User:allowSelfChange": true
}
Operation: DELETE /admin/v1/ApiKeys/e1eaf8a28e58485fb86f16f914fd08c7?allowSelfChange=true
Supporting Social JIT Provisioning with Group Membership Support
Use the API to manage new identity domain users with social Just-In-Time (JIT) user provisioning for first-time users.
OCI REST API now supports social JIT Provisioning, to automate user account creation when the user first tries to access identity domains when the user doesn't exist in the identity domain. Social JIT provisioning also supports granting group membership as part of user provisioning.
Attribute Definitions
- socialJitProvisioningEnabled: You can enable/disable social JIT by controlling this social attribute.
- jitProvGroupStaticListEnabled: When JIT is enabled, you can set this attribute to true to indicate social JIT user provisioning groups should be assigned from a static list.
- jitProvAssignedGroups: This attribute contains a list of groups to be assigned to each social JIT-provisioned user. JIT user-provisioning applies this static list when jitProvGroupStaticListEnabled is set to true.
Examples
Toggle Social JIT GroupMembership support: PATCH /admin/v1/SocialIdentityProviders/{idpID}
{
"Operations": [
{
"op": "replace",
"path": "socialJitProvisioningEnabled",
"value": true
},
{
"op": "replace",
"path": "jitProvGroupStaticListEnabled",
"value": true
},
{
"op": "add",
"path": "jitProvAssignedGroups",
"value": [
{
"value": “<identitydomain-group-id>”
}
]
}
],
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
]
}
{
"idcsCreatedBy": {
"type": "User",
"display": "admin opc",
"value": “<user-id>",
"$ref": "https://<domainURL>/admin/v1/Users/<user-id>"
},
"id": "<identity-provider-id>",
"meta": {
"created": "2024-04-29T17:26:15.646Z",
"lastModified": "2024-06-06T22:03:43.284Z",
"version": "<version number>",
"resourceType": "IdentityProvider",
"location": "https://<domainURL> /admin/v1/IdentityProviders/<identity-provider-id>"
},
"enabled": true,
"idcsLastModifiedBy": {
"value": "<user-id>",
"display": "admin opc",
"type": "User",
"$ref": "https://<domainURL>/admin/v1/Users/15ae5123456123456aa123456xxx123456"
},
"partnerName": "Google",
"ocid": “<domain-ocid>",
"socialJitProvisioningEnabled": true,
"jitProvGroupStaticListEnabled": true,
"accountLinkingEnabled": true,
"registrationEnabled": true,
"serviceProviderName": "Google",
"consumerSecret": "clientSecret12345",
"idAttribute": "email",
"consumerKey": "clientID12345",
"jitProvAssignedGroups": [
{
"value": "<idcs-group-id>",
"$ref": "https://<domain-id>/admin/v1/Groups/"<idcs-group-id>"
}
],
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:SocialIdentityProvider"
],
"name": "Google",
"showOnLogin": true
}
Fetch Group Membership for JIT enabled IDP: GET /admin/v1/SocialIdentityProviders/{idpId}?attributes=jitProvAssignedGroups
{
"id": "<identity-provider-id>",
"jitProvAssignedGroups": [
{
"value": "<idcs-group-id>",
"$ref": "https://<domain-id>/admin/v1/Groups/"<idcs-group-id>"
}
],
"name": "Google"
}
Remove particular group GUID from JIT enabled IDP membership list: PATCH /admin/v1/SocialIdentityProviders/{idpId}
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
],
"Operations": [
{
"op": "remove",
"path": "jitProvAssignedGroups[value eq \"<idcs-group-id>\"]"
}
]
}
{
"idcsCreatedBy": {
"type": "User",
"display": "admin opc",
"value": “<user-id>",
"$ref": "https://<domainURL>/admin/v1/Users/<user-id>"
},
"id": "<identity-provider-id>",
"meta": {
"created": "2024-04-29T17:26:15.646Z",
"lastModified": "2024-06-06T22:16:47.515Z",
"version": "<version number>",
"resourceType": "IdentityProvider",
"location": "https://<domainURL> /admin/v1/IdentityProviders/<identity-provider-id>"
},
"enabled": true,
"idcsLastModifiedBy": {
"value": "<user-id>",
"display": "admin opc",
"type": "User",
"$ref": "https://<domainURL>/admin/v1/Users/15ae5123456123456aa123456xxx123456"
},
"partnerName": "Google",
"ocid": “<domain-ocid>",
"socialJitProvisioningEnabled": true,
"jitProvGroupStaticListEnabled": true,
"accountLinkingEnabled": true,
"registrationEnabled": true,
"serviceProviderName": "Google",
"consumerSecret": "clientSecret12345",
"idAttribute": "email",
"consumerKey": "clientID12345",
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:SocialIdentityProvider"
],
"name": "Google",
"showOnLogin": true
}
Remove Group Membership list for IDP enabled IDP: PATCH /admin/v1/SocialIdentityProviders/{idpId}
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:PatchOp"
],
"Operations": [
{
"op": "remove",
"path": "jitProvAssignedGroups"
}
]
}
{
"idcsCreatedBy": {
"type": "User",
"display": "admin opc",
"value": “<user-id>",
"$ref": "https://<domainURL>/admin/v1/Users/<user-id>"
},
"id": "<identity-provider-id>",
"meta": {
"created": "2024-04-29T17:26:15.646Z",
"lastModified": "2024-06-06T22:16:47.515Z",
"version": "<version number>",
"resourceType": "IdentityProvider",
"location": "https://<domainURL> /admin/v1/IdentityProviders/<identity-provider-id>"
},
"enabled": true,
"idcsLastModifiedBy": {
"value": "<user-id>",
"display": "admin opc",
"type": "User",
"$ref": "https://<domainURL>/admin/v1/Users/15ae5123456123456aa123456xxx123456"
},
"partnerName": "Google",
"ocid": “<domain-ocid>",
"socialJitProvisioningEnabled": true,
"jitProvGroupStaticListEnabled": true,
"accountLinkingEnabled": true,
"registrationEnabled": true,
"serviceProviderName": "Google",
"consumerSecret": "clientSecret12345",
"idAttribute": "email",
"consumerKey": "clientID12345",
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:SocialIdentityProvider"
],
"name": "Google",
"showOnLogin": true
}
Managing Custom Claims
You can use the identity domains REST API to add custom claims to an access token, an identity token, or both the tokens.
Custom claims are rules that you can add to a token for the identity domain. There's no limit for the number of custom claims in a token. Token size is limited and the allowed values are "8000", "16000","32000", "128000".
https://<domainURL>/admin/v1/CustomClaims/{id}Resending Email Verifications When The Email Address Is Already Verified
After a user creates an account in an identity domain using the self-registration process, an email notification is sent to the user to verify the user's email address. After users verify their email addresses, they can no longer verify their email addresses after that.
However, identity domains also allow custom clients to reinitiate the change email flow for the same email address as many times as needed. To support this capability, you must set the triggerEmailVerificationFlowIfEmailAlreadyVerified attribute to true in the MeEmailVerifier request payload.
Use the following steps to trigger the email verification flow, if an email address is already verified:
Step 1: Create a User
This step shows how to create a user by submitting a POST request on the REST resource using cURL. For more information about cURL, see Use cURL.
curl
-X POST
-H "Content-Type:application/json"
-H "Authorization: Bearer <Access Token Value>"https://<domainURL>/admin/v1/Users
The command in this example uses the URL structure
https://<domainURL>/resource-path, where <domainURL> represents the identity domain URL, and the resource path represents the identity domain API. See Send Requests for the appropriate URL structure to use.Example of Request Body
The following shows an example of a request body in JSON format:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User"
],
"userName": "bjensen@example.com",
"password": "{{password}}",
"name": {
"familyName": "Jensen",
"givenName": "Barbara",
"middleName": "Jane"
},
"emails": [
{
"value": "bjensen@example.com",
"type": "work",
"primary": true
}
]
}
Example of Response Body
The following shows an example of the response body:
{
"idcsCreatedBy": {
"type": "User",
"display": "admin opc",
"value": "6aa2585abd464991929bcf05ace532e9",
"$ref": "[https://<domainURL>/admin/v1/Users/6aa2585abd464991929bcf05ace532e9]"
},
"id": "ff9a9207fc8c4fd2b3d76af84235e8fd",
"meta": {
"created": "2022-03-01T05:19:52.765Z",
"lastModified": "2022-03-01T05:19:52.765Z",
"resourceType": "User",
"location": "[https://<domainURL>/admin/v1/Users/ff9a9207fc8c4fd2b3d76af84235e8fd]"
},
"active": true,
"displayName": "Barbara Jensen",
"idcsLastModifiedBy": {
"value": "6aa2585abd464991929bcf05ace532e9",
"display": "admin opc",
"type": "User",
"$ref": "[https://<domainURL>/admin/v1/Users/6aa2585abd464991929bcf05ace532e9]"
},
"userName": "bjensen2",
"emails": [
{
"verified": false,
"primary": false,
"secondary": false,
"value": "[bjensen@example.com|mailto:bjensen@example.com]",
"type": "recovery"
},
{
"verified": false,
"primary": true,
"secondary": false,
"value": "[bjensen@example.com|mailto:bjensen@example.com]",
"type": "work"
}
],
"urn:ietf:params:scim:schemas:example:idcs:extension:userState:User": {
"locked": {
"on": false
}
},
"name": {
"familyName": "Jensen",
"givenName": "Barbara",
"formatted": "Barbara Jane Jensen",
"middleName": "Jane"
},
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:example:idcs:extension:userState:User"
]
}
Step 2: Get a User
This step shows how to retrieve a user by the user's ID by submitting a GET request on the REST resource using cURL. For more information about cURL, see Use cURL.
curl
-X GET
-H "Content-Type:application/scim+json"
-H "Authorization: Bearer <Access Token Value>"https://<domainURL>/admin/v1/Users/<user_ocid or user_id>
The command in this example uses the URL structure
https://<domainURL>/resource-path, where
<domainURL> represents the Identity Service URL, and the
resource path represents the Identity Service API. See Send Requests for the
appropriate URL structure to use.Example of Response Body
The following example shows the contents of the response body in JSON format:
{
"displayName": "Barbara Jensen",
"name": {
"givenName": "Barbara",
"formatted": "Barbara Jane Jensen",
"middleName": "Jane",
"familyName": "Jensen"
},
"urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User": {
"locked": {
"on": false
}
},
"userName": "bjensen@example.com",
"id": "ff9a9207fc8c4fd2b3d76af84235e8fd",
"active": true,
"emails": [
{
"verified": "false",
"value": "bjensen@example.com",
"type": "recovery"
},
{
"primary": true,
"value": "bjensen@example.com",
"type": "work"
}
],
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User",
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"meta": {
"resourceType": "User",
"created": "2022-07-13T07:28:59.227Z",
"lastModified": "2022-07-13T07:28:59.227Z",
"location": "http://<domainURL>/admin/v1/Users/ff9a9207fc8c4fd2b3d76af84235e8fd"
},
"idcsCreatedBy": {
"value": "f8fa30db0f5f41f98de00bc07c05a73d",
"$ref": "/OAuthClients/f8fa30db0f5f41f98de00bc07c05a73d",
"type": "OAuthClient",
"display": "admin"
},
"idcsLastModifiedBy": {
"value": "f8fa30db0f5f41f98de00bc07c05a73d",
"$ref": "/OAuthClients/f8fa30db0f5f41f98de00bc07c05a73d",
"type": "OAuthClient",
"display": "admin"
}
}
Step 3: Initiate Self-Service Email Verification
This step shows how to initiate email validation of either the user's primary or recovery email address by submitting a PUT request on the REST resource using cURL. For more information about cURL, see Using cURL.
curl
-X PUT
-H "Content-Type:application/scim+json"
-H "Authorization: Bearer <Access Token Value>"https://<domainURL>/admin/v1/MeEmailVerifier
Example of Request Body
The following shows an example of a request body in JSON format:
{
"email": "bjensen@example.com",
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:MeEmailVerifier"
],
"id": "ff9a9207fc8c4fd2b3d76af84235e8fd",
"userFlowControlledByExternalClient": true,
"triggerEmailVerificationFlowIfEmailAlreadyVerified": true
}
Example of Response Body
The following example shows the contents of the response body in JSON format:
{
"email": "bjensen@example.com",
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:MeEmailVerifier"
],
"id": "ff9a9207fc8c4fd2b3d76af84235e8fd",
"userFlowControlledByExternalClient": true,
"triggerEmailVerificationFlowIfEmailAlreadyVerified": true,
"meta": {
"resourceType": "MeEmailVerifier",
"location": "https://<domainURL>/admin/v1/MeEmailVerifier/57044ca14d274d789a586e5ec77c26f3"
},
"userToken": {
"value": "db21a3578d27439ca9fab6349be46c30",
"$ref": "https://<domainURL>/admin/v1/UserTokens/db21a3578d27439ca9fab6349be46c30"
}
}
Step 4: Obtain a User Token
This step shows how to retrieve a user token using its ID by submitting a GET request on the REST resource using cURL. For more information about cURL, see Using cURL.
curl
-X GET
-H "Content-Type:application/scim+json"
-H "Authorization: Bearer <Access Token Value>"https://<domainURL>/admin/v1/UserTokens/{{usertokenid}}
Example of Response Body
The following example shows the contents of the response body in JSON format:
{
"expiryTime": "2022-07-13T07:28:59.227Z",
"token": "KtXTrZkyIC2OWYVChbYEtfWnE7zhxlYJ0roEvsj0F2I=",
"tokenType": "email",
"userId": "5a7550ad5cfa4f50bdc608da1831481b",
"data": "bjensen@example.com",
"eventId": "admin.user.password.reset.success",
"status": 0,
"id": "3e4b69e99ddf472989e089a904a3c1a7",
"meta": {
"created": "2022-07-13T07:28:59.227Z",
"lastModified": "2022-07-13T07:28:59.227Z",
"resourceType": "UserToken",
"location": "$baseUri/UserTokens/{id}"
},
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:UserToken"
],
"idcsCreatedBy": {
"value": "14171fc6031a417cac680cdb9d82c2ea",
"display": "admin",
"type": "OAuthClient",
"$ref": "$baseUri/OAuthClient/{id}"
},
"idcsLastModifiedBy": {
"value": "14171fc6031a417cac680cdb9d82c2ea",
"display": "admin",
"type": "OAuthClient",
"$ref": "$baseUri/OAuthClient/{id}"
}
}
Step 5: Self-Verify Email Address
This step shows how to verify a new email address by submitting a POST request on the REST resource using cURL. This endpoint validates the token, and then marks the email address as verified. For more information about cURL, see Use cURL.
curl
-X POST
-H "Content-Type:application/scim+json"
-H "Authorization: Bearer <Access Token Value>"https://<domainURL>/admin/v1/MeEmailVerified
Example of Request Body
The following shows an example of a request body in JSON format:
{
"token": "YzQwYTc4NmE5YmEzNGU4MDg0YjFkY2FhZWRmNThlOTc6TEFGaWtuTXI5OjIwMTUtMDctMjRUMDI6Mjk6NDEuNzEwWg==",
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:MeEmailVerified"
]
}
Example of Response Body
The following example shows the contents of the response body in JSON format:
{
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:extension:MeEmailVerified"
],
"id": "5fed0efce51f40b4a42b0773a65178c3",
"meta": {
"resourceType": "MeEmailVerified",
"location": "https://<domainURL>/admin/v1/MeEmailVerified/57044ca14d274d789a586e5ec77c26f3"
}
}
Enrolling in MFA using the SMS Factor Using Self Service
This use case provides a step-by-step example of using the identity domains REST API for Self-Service enrollment in Multifactor Authentication (MFA) using SMS Factor.
Download the identity domains authentication use case examples collection and the global variables file from the idcs-rest-clients folder within the idm-samples GitHub repository and then import them into Postman.
As a prerequisite step, you must obtain a ME token before following these steps. See Generating Access Token Using Authentication API for information on obtaining a ME token.
These steps assume that relevant factors of MFA are enabled using Configure Multifactor Authentication Settings.
Step1: Create the Self Service Enrollment Using the SMS Factor
This step initiates SMS enrollment in a POST request to the
/admin/v1/MyAuthenticationFactorEnroller endpoint. The client
must include the following attributes:
value: defines the user id. You can make a GET call to{{HOST}}/admin/v1/Meto get the "id" value.displayName: defines the display name for the devicecountryCode: defines the country code of the phone number where the SMS text will be sentphoneNumber: defines the phone number where the SMS text will be sent
Request Example
The following example shows the contents of the POST request body in JSON format:
{
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:AuthenticationFactorEnroller"
],
"user": {
"value": "c810ff4522eb437abac013291c1984d1"
},
"displayName": "Joe's Personal Phone",
"countryCode": "+44",
"phoneNumber": "1122334455",
"authnFactors": [
"SMS"
]
}
Response Example
The following example shows the contents of the response body in JSON format:
{
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:AuthenticationFactorEnroller"
],
"user": {
"value": "c810ff4522eb437abac013291c1984d1",
"$ref": "https://example.identitycloud.com/admin/v1/Users/c810ff4522eb437abac013291c1984d1"
},
"displayName": "Joe's Personal Phone",
"countryCode": "+44",
"phoneNumber": "XXXXXXX455",
"authnFactors": [
"SMS"
],
"meta": {
"resourceType": "MyAuthenticationFactorEnroller",
"location": "https://example.identitycloud.com/admin/v1/MyAuthenticationFactorEnroller"
},
"deviceId": "92142250e2ab4608b5c6532eb73e3d7c",
"requestId": "a0a7f9bf-13a8-43f3-bcc7-2087dc3f7a18o-o1548346179"
}
In the response, the deviceId and the requestId
should be passed in the next step.
Error Response Examples
userId is invalid. You get a 400 HTTP response code. {
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:Error",
"urn:ietf:params:scim:api:oracle:idcs:extension:messages:Error"
],
"detail": "AuthenticationFactorEnroller.user references a User with ID 1fa35f74491d44ef5a7cc25bfdb1c8b1c that does not exist.",
"status": "400",
"urn:ietf:params:scim:api:oracle:idcs:extension:messages:Error": {
"messageId": "error.common.validation.invalidReferenceResource"
}
}The following example shows the error message in JSON format if a
phoneNumber is incorrect. You get a 400 HTTP response code.
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:Error",
"urn:ietf:params:scim:api:oracle:idcs:extension:messages:Error"
],
"detail": "Your phone number +91123 is not valid.",
"status": "400",
"urn:ietf:params:scim:api:oracle:idcs:extension:messages:Error": {
"messageId": "error.ssocommon.auth.invalidPhoneNumber",
"additionalData": {
"params": "+91123",
"msgId": "error.ssocommon.auth.invalidPhoneNumber"
}
}
}
Step 2: Initiate the Self Service Enrollment Using the OTP by SMS
This step requests that the OTP be sent through SMS in a POST request to the /admin/v1/MyAuthenticationFactorInitiator endpoint. The client must include the following attributes:
requestId: received in the Step 1 response
deviceId: received in the Step 1 response
userName: username of the user
Request Example
The following example shows the contents of the POST request body in JSON format:
{
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:AuthenticationFactorInitiator"
],
"deviceId": "92142250e2ab4608b5c6532eb73e3d7c",
"requestId": "a0a7f9bf-13a8-43f3-bcc7-2087dc3f7a18o-o1548346179",
"userName": "jbloggs",
"authFactor": "SMS"
}
Response Example
The following example shows the contents of the response in JSON format:
{
"deviceId": "92142250e2ab4608b5c6532eb73e3d7c",
"requestId": "a0a7f9bf-13a8-43f3-bcc7-2087dc3f7a18o-o1548346179",
"authFactor": "SMS",
"userName": "jbloggs",
"displayName": "Joe's Personal Phone",
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:AuthenticationFactorInitiator"
]
}
An OTP code is sent by using SMS to the user's mobile device. In the response deviceId and requestId should be passed in the next step.
2a. Initiate the Self Service Enrollment Request to Resend OTP by SMS
In case the user wants the server to "resend" the OTP, then same payload as mentioned in the Step 2 should be sent to the server again.
Request Example
The following example shows the contents of the POST request body in JSON format:
{
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:AuthenticationFactorInitiator"
],
"deviceId": "92142250e2ab4608b5c6532eb73e3d7c",
"requestId": "a0a7f9bf-13a8-43f3-bcc7-2087dc3f7a18o-o1548346179",
"userName": "jbloggs",
"authFactor": "SMS"
}
Response Example
The following example shows the contents of the response in JSON format:
{
"deviceId": "92142250e2ab4608b5c6532eb73e3d7c",
"requestId": "a0a7f9bf-13a8-43f3-bcc7-2087dc3f7a18o-o1548346179",
"authFactor": "SMS",
"userName": "jbloggs",
"displayName": "Joe's Personal Phone",
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:AuthenticationFactorInitiator"
]
}
An OTP code is sent using SMS to the user's mobile device. In the response
deviceId and requestId should be passed in the
next step.
Step 3: Validate the Self Service Enrollment Using the OTP
This step validates the SMS enrollment of a user in a POST request to the
/admin/v1/MyAuthenticationFactorValidator endpoint.
The client must include the following attributes:
otpCode:the code received by the user on their device-
requestId:received in the Step 2 response deviceId:received in the Step 2 response
Request Example
The following example shows the contents of the POST request in JSON format:
{
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:AuthenticationFactorValidator"
],
"deviceId": "92142250e2ab4608b5c6532eb73e3d7c",
"requestId": "a0a7f9bf-13a8-43f3-bcc7-2087dc3f7a18o-o1548346179",
"otpCode": "191224",
"authFactor": "SMS",
"scenario": "ENROLLMENT"
}
Response Example
The following example shows the contents of the response in JSON format:
{
"authFactor": "SMS",
"deviceId": "92142250e2ab4608b5c6532eb73e3d7c",
"requestId": "a0a7f9bf-13a8-43f3-bcc7-2087dc3f7a18o-o1548346179",
"scenario": "ENROLLMENT",
"status": "SUCCESS",
"displayName": "Joe's Personal Phone",
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:AuthenticationFactorValidator"
],
"mfaStatus": "ENROLLED",
"mfaPreferredDevice": "2b27b8c072d64b899d41c8470acea32a",
"mfaPreferredAuthenticationFactor": "SMS",
"securityQuestionsPresent": false,
"devicesCount": 3,
"emailFactorEnrolled": true
}
mfaStaus:"ENROLLED" indicates that user has enrolled for MFA. The mfapreferredAuthenticationFactor attribute indicates the factor set as the preferred method. In this case, it's SMS.This value may be different, if the first enrolled factor is different from SMS.
Error Response Examples
The following example shows the error message in JSON format if OTP is incorrect. You get a 401 HTTP response code and the enrollment fails.
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:Error",
"urn:ietf:params:scim:api:oracle:idcs:extension:messages:Error"
],
"detail": "Invalid passcode.",
"status": "401",
"urn:ietf:params:scim:api:oracle:idcs:extension:messages:Error": {
"messageId": "error.ssocommon.auth.invalidPasscode"
}
}
Resetting Authentication Factors for Multiple Users Using The Bulk Endpoint
You can use the Bulk endpoint to reset the authentication factors for up to 40 users at a time using a POST call.
Sample Request
curl
-X POST
-H "Content-Type:application/scim+json"
-H "Authorization: Bearer <Access_Token>"
https://<domainURL>/admin/v1/Bulk
Sample Payload
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:BulkRequest"
],
"Operations": [
{
"method": "POST",
"path": "/AuthenticationFactorsRemover",
"bulkId": "<bulkid1>",
"data": {
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:AuthenticationFactorsRemover"
],
"user":
{ "value": "<user_1_id>" }
}
},
{
"method": "POST",
"path": "/AuthenticationFactorsRemover",
"bulkId": "<bulkid2>",
"data": {
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:AuthenticationFactorsRemover"
],
"user":
{ "value": "<user_2_id>" }
}
}
]
}
Using the onBehalfOf Allowed Operation
The onBehalfOf allowed operation provides a way to ensure that access privileges can be generated from the user's privileges alone, so that a client application can access endpoints to which the user has access, even if the client application by itself wouldn't normally have access.
When an authorized client application implements functionality that requires it to access identity domains endpoints, that client is granted the necessary privileges to do so. A web application client, on the other hand, implements functionality that requires the client application to access endpoints using the privileges and scopes acquired from the logged-in user. With identity domains default authorization behavior, that client must still have the full set of privileges required to access those endpoints without regard to the privileges granted to the user. The onBehalfOf allowed operation provides an administrator a way to indicate that the user's privileges alone should be used rather than an intersection of the user's scopes (if a user is present) and the client's scopes.
Public or CLI applications have very limited privileges or no privileges to access endpoints. These types of clients rely on the user who is accessing the application to drive what rights the application has. When a user is accessing a public application, if the user was issued an access token that's constructed from the user's privileges alone, that user would be able to access the endpoints as long as the user is authorized.
The onBehalfOf allowed operation enables you to generate such an access token for the OAuth Client application. When computing the identity domains specific scopes (scopes that begin with "urn:opc:idm:") to set in the access token, identity domains ignores the client's privileges and uses a scope equal to or less than the scope originally granted to the authorized user. So, only the user's privileges (admin roles, groups, and so on) in conjunction with the requested scopes are used to determine access. If the requested scope "urn:opc:idm:_myscopes_" is used, then all scopes that are granted to the user are returned.
Enabling the onBehalfOf Allowed Operation
Use the identity domains REST API to create or update an OAuth application, and specify onBehalfOfUser as an allowed operation. When you create an OAuth application using the identity domains UI, on the Authorization page, select the checkbox for the On behalf Of allowed operation. When users access the application, they can perform various functions based on their permissions.
Example
The example shows how to create an application and specify the
onBehalfOfUser allowed operation (in bold in the example).
cat</tmp/OAuthClientApp.json << __EOF__
{
"schemas": [
"urn:ietf:params:scim:schemas:oracle:idcs:App"
],
"displayName": "publicClientApp",
"isOAuthClient": true,
"description": "public client",
"active": true,
"clientType": "public",
"basedOnTemplate": {
"value": "CustomBrowserMobileTemplateId"
},
"redirectUris": [
"http://example.com:9090/demoapp/return",
"http://example.com:9090/IDCSPlayground"
],
"logoutUri": "http://example.com:9090/demoapp/logout.jsp",
"postLogoutRedirectUris": ["http://example.com:9090/demoapp/logout.jsp"],
"allowedScopes": [
{
"fqs": "http://example.com/photos"
},
{
"fqs": "http://example.com/presentations"
},
{
"fqs": "http://example.com/documents"
}
],
"allowedOperations": [
"onBehalfOfUser" ],
"allowedGrants": [
"authorization_code",
"implicit"
]
}
__EOF__
curl -X POST
-H "Content-type: application/json"
-H "Authorization: Bearer <access token value>"
--data @/tmp/OAuthClientApp.json http://<domainURL>/admin/v1/Apps
Using the Audit Event APIs
Identity domains Audit Events REST endpoints enable you to get Audit logs covering significant events, changes, or actions. Using these APIs, you can integrate all Security Information and Event Management (SIEM), User and Entity Behavior Analytics (UEBA), and Cloud Access Security Broker (CASB) to poll Audit data.
Identity domains AuditEvents and certain reports templates in the Reports APIs will stop returning new data after December 15, 2024. Instead, you can use the OCI Audit service to get this data. To view service change announcements for IAM, see IAM Service Change Announcements.
Audit events enable you to review the actions performed by members of your organization using details provided by the Audit logs, such as who performed the action and what the action was. Identity domains is the central point of control for all activities happening in the system. It generates audit data in response to all administrator and end-user operations, such as User Login, Application Access, Password Reset, User Profile Update, CRUD operations on Users, Group, Applications, and so on.
Audit event-related dates and times use the Coordinated Universal Time (UTC) format: YYYY-MM-DDThh:mm:ss.mscZ. For example, 2022-03-24T10:24:24.022Z.
Comprehensive reports can be generated from many administrator and user activities, such as those on the left side of the diagram. Represented on the right side are examples of the historical user activity that you can capture and the statistics and analytics that you can generate by importing data into analytics tools.
Audit Examples
Audit examples are available to help get you up to speed. After you import the collection, type "audit" in the filter to find all the audit requests. Download the identity domains authentication use case examples collection and the global variables file from the idcs-rest-clients folder within the idm-samples GitHub repository and then import them into Postman.
Identity Domains Audit Events
This table provides Event IDs of some of the most crucial events in identity domains.
| Event Category | Event | Event ID |
|---|---|---|
|
Single Sign-On |
User Logins Success |
sso.session.create.success
|
|
Single Sign-On |
User Logins Failure |
sso.authentication.failure
|
|
Application Access Events |
Application Access Success |
sso.app.access.success
|
|
Application Access Events |
Application Access Failure |
sso.app.access.failure
|
|
Multifactor Authentication |
Step-up authentication for User |
sso.auth.factor.initiated
|
|
Multifactor Authentication |
ByPass Code Creation |
sso.bypasscode.create.success
|
|
Multifactor Authentication |
ByPass Code Deletion |
sso.bypasscode.delete.success
|
|
Self-Registration |
User Self-Registration success |
admin.me.register.success
|
|
Self-Service Access Request |
Access Request Success |
admin.myrequest.create.success
|
|
Notifications |
Notification Delivery success |
notification.delivery.success
|
|
Notifications |
Notification Delivery Failure |
notification.delivery.failure
|
|
Identity Bridge Sync |
ID Bridge Sync Success |
idbridge.sync.success
|
|
Identity Bridge Sync |
ID Bridge Sync Failure |
idbridge.sync.failure
|
|
Forgot/Reset Password |
Password Reset success |
admin.me.password.reset.success
|
|
Reset Password Initiated by Administrator |
Password Reset success |
admin.user.password.reset.success
|
|
Change Password |
Password Change Success |
admin.me.password.change.success
|
|
Change Password |
Password Change Failure |
admin.me.password.change.failure
|
|
User CRUD Operations |
User Create Success |
admin.user.create.success
|
|
User CRUD Operations |
User Activate Success |
admin.user.activated.success
|
|
User CRUD Operations |
User Update Success |
admin.user.update.success
|
|
User CRUD Operations |
User Delete Success |
admin.user.delete.success
|
|
Group CRUD Operations |
Group Create Success |
admin.group.create.success
|
|
Group CRUD Operations |
Group Update Success |
admin.group.update.success
|
|
Group CRUD Operations |
Group Delete Success |
admin.group.delete.success
|
|
Group CRUD Operations |
Group Membership Assignment |
admin.group.add.member.success
|
|
Group CRUD Operations |
Group Membership Removal |
admin.group.remove.member.success
|
|
Application CRUD Operations |
Application Create |
admin.app.create.success
|
|
Application CRUD Operations |
Application Update |
admin.app.update.success
|
|
Application CRUD Operations |
Application Delete |
admin.app.delete.success
|
|
User Provisioning |
Successful User Provisioning |
admin.account.create.success
|
|
User Provisioning |
Unsuccessful User Provisioning |
admin.account.delete.success
|
Event Resources
The following table describes crucial event resources.
| Event Resource | Description |
|---|---|
|
eventID |
Event ID as defined by the identity domains components |
|
actorName |
Username (login name) from the security context |
|
actorDisplayName |
User display name from the security context |
|
actorId |
User GUID from the security context |
|
actorType |
The actor type, either User or Client |
|
ssoSessionId |
Cloud SSO identifier |
|
ssoIdentityProvider |
SSO Identity Provider |
|
ssoAuthFactor |
The Authentication Factor used for authentication |
|
ssoApplicationId |
Application identifier GUID |
|
ssoApplicationType |
SSO Application Type: Application Type indicates whether the application is an OPC or a NonOPC application and whether the type is SAML, OAuth, or Secure Form Fill based on the protocol. |
|
clientIp |
IP address of the client application that's making the request |
|
ssoUserAgent |
User's device information |
|
ssoPlatform |
Platform used to perform authentication |
|
ssoProtectedResource |
Protected resource URI (Resource host, port, and context) |
|
ssoMatchedSignOnPolicy |
Matched Sign-On Policy, added in version18.1.2 |
|
Message |
Message for event-specific success or failure |
|
Timestamp |
Timestamp of when the event occurred |
Audit Schema
You can find the Audit Schema using the identity domains REST API. The Audit Schema contains all the information discussed in the tables of this use case.
Example Request
Perform a GET on the /Schemas endpoint using the
AuditEvent schema.
GET <domainURL>>/admin/v1/Schemas/urn:ietf:params:scim:schemas:oracle:idcs:AuditEvent
Example Response Snapshot
The following is a snapshot of the response.
{
"attributes": [
{
"caseExact": false,
"description": "Unique URI of the schema",
"idcsDisplayName": "ID",
"idcsSearchable": true,
"multiValued": false,
"mutability": "readOnly",
"name": "id",
"required": true,
"returned": "always",
"type": "string",
"uniqueness": "global"
},
{
"caseExact": false,
"description": "An identifier for the Resource as defined by the Service Consumer. The externalId may simplify identification of the Resource between Service Consumer and Service Provider by allowing the Consumer to refer to the Resource with its own identifier, obviating the need to store a local mapping between the local identifier of the Resource and the identifier used by the Service Provider. Each Resource MAY include a non-empty externalId value. The value of the externalId attribute is always issued by the Service Consumer and can never be specified by the Service Provider. The Service Provider MUST always interpret the externalId as scoped to the Service Consumer's tenant.",
"idcsDisplayName": "External ID",
"idcsSearchable": false,
"multiValued": false,
"mutability": "readWrite",
"name": "externalId",
"required": false,
"returned": "default",
"type": "string",
"uniqueness": "none"
},
{
"caseExact": true,
"description": "Event correlation ID (ECID) correlating a chain of events as belonging to the same business operation (root task). ECID is generated when the request enters the IDCS web tier.",
"idcsDisplayName": "Execution Context Id",
"idcsSearchable": true,
"multiValued": false,
"mutability": "readWrite",
"name": "ecId",
"required": false,
"returned": "default",
"type": "string",
"uniqueness": "none"
},
{
"caseExact": true,
"description": "Relationship Identifier (RID). This value indicates the position of a particular event/sub-operation within the tree of tasks that begins with the root task.",
"idcsDisplayName": "Relationship Id",
"idcsSearchable": true,
"multiValued": false,
"mutability": "readWrite",
"name": "rId",
"required": false,
"returned": "default",
"type": "string",
"uniqueness": "none"
},
{
"caseExact": false,
"description": "Timestamp of when the event occurred, provided by the Event Manager (not supplied by clients)",
"idcsDisplayName": "Timestamp",
"idcsSearchable": true,
"multiValued": false,
"mutability": "readWrite",
"name": "timestamp",
"required": false,
"returned": "default",
"type": "dateTime",
"uniqueness": "none"
},