Hosted Login Quick Start Provisioning Guide

Purpose

Mission Statement

The purpose of this document is to guide developers through a basic implementation of Hosted Login. Further customizations can be made as needed, but are outside the scope of this Quick Start Guide.

Audience

The audience for this document is developers for Akamai Identity Cloud customers who are in the delivery phase for Hosted Login and are ready to get an implementation up-and-running.

This guide assumes the audience is already familiar with:

  • Making API calls
  • Working with:
    • Capture applications
    • Capture client settings
    • Schemas
    • Flows

It also assumes the audience has an existing website or app with which to integrate Hosted Login.

Contents

The Quick Start Guide uses an 8-step process to assist you with provisioning and configuring Hosted Login:

  1. Akamai provides basic elements to enable an implementation of Hosted Login
  2. Get a token to use in configuration endpoints
  3. Create a token policy
  4. Create a login policy
  5. Create an OIDC client
  6. Add Capture client settings
  7. Call Hosted Login from your site/app
  8. Create CNAMEs

Step 1: Akamai provides basic elements to enable an implementation of Hosted Login

Schema

Akamai provides a new schema (or adds to an existing schema as appropriate) to include all the attributes necessary for Hosted Login to function properly.

Flow

Akamai provides a new flow built specifically for Hosted Login.

Customer ID

Akamai provides your Hosted Login Customer ID. This is used by all Hosted Login endpoints to point to your core customer account for Hosted Login.

OIDC Configuration Client

Akamai provides the client ID and client secret for your initial OIDC configuration client. This is a confidential client which will have access to all your Hosted Login configuration endpoints.

Step 2: Get a token to use in configuration endpoints

Call the /login/token endpoint to request a token with the API scopes needed for configuration.

When configuring Basic authorization for this call, use your OIDC configuration client ID as the username and the OIDC configuration client secret as the password.

Request Template

curl -X POST \
  https://v1.api.<region>.janrain.com/<customer-id>/login/token \
   -H 'Authorization: Basic <Base64-encoded-client_id:client_secret>' \
   -F 'grant_type=client_credentials' \
   -F 'scope=<allowed-config-endpoints>'

Example Request

curl -X POST \
  https://v1.api.us.janrain.com/12345678-1234-1234-1234-123456789012/login/token \
  -H 'Authorization: Basic N2JhNTE2NjEtMWE3ZS0...1BVU1vbGdRRUVLQlpwdlRB' \
  -F 'grant_type=client_credentials' \
  -F 'scope=*:config/**'

Example Response

{
    "access_token": "abc1deA2BfgCDEFhGiHjIJKkL3l4MmnNopOPqQR-Srst-5T6UuvV7WXw8YZx9y0A",
    "expires_in": 3600,
    "token_type": "Bearer",
    "scope": "*:config/**"
}

The scope in this example allows full read/write access to all Hosted Login endpoints for your Customer ID. If you want to limit the scope to a specific endpoint or subset of endpoints, and/or you want to allow only certain actions on those endpoints, you can adjust this value accordingly. Scope formatting is documented here.

Scope Examples

To create a token that can ... Use this scope syntax
Read (GET) all token policies, login policies, and OIDC clients 'scope=.:config/**'
Read (GET) and configure (POST, PUT) all token policies 'scope=*:config/tokenPolicies**'
Read (GET) all token policies and all login policies (separated by a space) 'scope=.:config/tokenPolicies** .:config/loginPolicies**'
Read (GET) a specific login policy 'scope=.:config/loginPolicies/1ab23c45-6789-0123-d4ef-5g678h90ijk1'
Read (GET) and configure (PUT) a specific login policy 'scope=*:config/loginPolicies/1ab23c45-6789-0123-d4ef-5g678h90ijk1'
Read (GET) and configure (PUT) the token policy, login policy, and OIDC client for a specific property (separated by a space) 'scope=*:config/tokenPolicies/a123bcde-4f56-7890-gh12-i34j567k8l90 *:config/loginPolicies/1ab23c45-6789-0123-d4ef-5g678h90ijk1 *:config/clients/1ab23456-7c8d-90ef-g123-45hij6789012'

Step 3: Create a Token Policy

Call the /config/tokenPolicies endpoint using the POST method to create a token policy for your Hosted Login implementation.

When configuring Bearer token authorization for this call, use the configuration token you provisioned in step 2.

Request Template

curl -X POST \
https://v1.api.<region>.janrain.com/<customer-id>/config/tokenPolicies \
  -H 'Authorization: Bearer <token> \
  -H 'Content-Type: application/json' \
  -d '{
  "accessTokenLifetime": <lifetime-in-seconds>,
  "allowedScopes": [
    "<scope>",
    "<scope>",
    ...
  ],
  "refreshTokenLifetime": <lifetime-in-seconds>,
  "title": "<new-token-policy-name>"
}'

Example Request

curl -X POST \
https://v1.api.us.janrain.com/12345678-1234-1234-1234-123456789012/config/tokenPolicies \
  -H 'Authorization: Bearer 123abc456...def789ghi' \
  -H 'Content-Type: application/json' \
  -d '{
  "accessTokenLifetime": 3600,
  "allowedScopes": [
    "openid",
    "profile",
    "email",
    "address",
    "phone"
  ],
  "refreshTokenLifetime": 36000,
  "title": "Property 1 Token Policy"
}'

Example Response

"a123bcde-4f56-7890-gh12-i34j567k8l90"

The response contains the ID of the token policy you just created. If you want to review the full token policy you just created, call the /config/tokenPolicies/<token-policy-id> endpoint using the GET method.

Step 4: Create a Login Policy

Call the /config/loginPolicies endpoint using the POST method to create a login policy for your Hosted Login implementation.

When configuring Bearer token authorization for this call, use the configuration token you provisioned in step 2.

Request Template

curl -X POST \
https://v1.api.<region>.janrain.com/<customer-id>/config/loginPolicies \
  -H 'Authorization: Bearer <token> \
  -H 'Content-Type: application/json' \
  -d '{
  "identityStoreDetails": {
    "connectionDetails": {
      "applicationId": "<capture-app-id>",
      "clientId": "<capture-app-owner-client-id>",
      "clientSecret": "<capture-app-owner-client-secret>",
      "domain": "<provided-by-akamai>",
      "entityType": "<entity-type>"
    },
    "type": "janrainCapture"
  },
  "loginURL": "https://v1.api.<region>.janrain.com/<customer-id>/auth-ui/login",
  "title": "<new-login-policy-name>"
}'

Example Request

curl -X POST \
https://v1.api.us.janrain.com/12345678-1234-1234-1234-123456789012/config/loginPolicies \
  -H 'Authorization: Bearer 123abc456...def789ghi' \
  -H 'Content-Type: application/json' \
  -d '{
  "identityStoreDetails": {
    "connectionDetails": {
      "applicationId": "1abcdef2g3hijklmno4pqrs5tu",
      "clientId": "abc123defg4h5i67jklmnopqrstuvw89",
      "clientSecret": "12a34bc5d67ef8ghij9klmn01o2pqrst",
      "domain": "dev-app.janraincapture.com",
      "entityType": "user"
    },
    "type": "janrainCapture"
  },
  "loginURL": "https://v1.api.us.janrain.com/12345678-1234-1234-1234-123456789012/auth-ui/login",
  "title": "Property 1 Login Policy"
}'

Example Response

"1ab23c45-6789-0123-d4ef-5g678h90ijk1"

The response contains the ID of the login policy you just created. If you want to review the full login policy you just created, call the /config/loginPolicies/<login-policy-id> endpoint using the GET method.

Step 5: Create an OIDC Client

Call the /config/clients endpoint using the POST method to create an OIDC client for your Hosted Login implementation.

When configuring Bearer token authorization for this call, use the configuration token you provisioned in step 2.

Request Template

curl -X POST \
https://v1.api.<region>.janrain.com/<customer-id>/config/clients \
  -H 'Authorization: Bearer <token> \
  -H 'Content-Type: application/json' \
  -d '{
  "loginPolicy": "<login-policy-id>",
  "name": "<new-oidc-client-name>",
  "redirectURIs": [
    "<redirect-uri>"
  ],
  "tokenPolicy": "<token-policy-id>",
  "type": "<confidential-or-public>"
}'

Example Request

curl -X POST \
https://v1.api.us.janrain.com/12345678-1234-1234-1234-123456789012/config/clients \
  -H 'Authorization: Bearer 123abc456...def789ghi' \
  -H 'Content-Type: application/json' \
  -d '{
  "loginPolicy": "1ab23c45-6789-0123-d4ef-5g678h90ijk1",
  "name": "Property 1 OIDC Client",
  "redirectURIs": [
    "https://mydomain.com"
  ],
  "tokenPolicy": "a123bcde-4f56-7890-gh12-i34j567k8l90",
  "type": "public"
}'

Example Response

{
    "id": "1ab23456-7c8d-90ef-g123-45hij6789012",
    "name": "Property 1 OIDC Client",
    "redirectURIs": [
        "https://mydomain.com"
    ],
    "loginPolicy": "1ab23c45-6789-0123-d4ef-5g678h90ijk1",
    "tokenPolicy": "a123bcde-4f56-7890-gh12-i34j567k8l90",
    "type": "public",
    "_links": {
        "self": {
            "href": "/config/12345678-1234-1234-1234-123456789012/clients/1ab23456-7c8d-90ef-g123-45hij6789012"
        },
        "application_client": {
            "href": "/config/1abcdef2g3hijklmno4pqrs5tu/clients/abcdefghi12jkl3m4nopqr5stuvwxy67"
        }
    }
}

The response contains the ID of the OIDC client you just created. If you want to review this client configuration in the future, call the /config/clients/{client_id} endpoint with the GET method.

Note: The client secret is returned in the response when you create a confidential client. If you need to access the secret in the future, call the /config/clients/{client_id}/secret endpoint with the GET method.

Add Capture Client Settings

Note: All Example Values in the tables below are examples only. Your values will be different in most cases.

Creating a new OIDC client (in the previous step) automatically creates a Capture login client with the following settings and the appropriate values in place:

Setting Name Example Value
janrainOidcClientId 1ab23456-7c8d-90ef-g123-45hij6789012
site_name Property 1 OIDC Client
user_entity_type user
password_recover_url https://v1.api.us.janrain.com/12345678-1234-1234-1234-123456789012/auth-ui/reset-password?client_id=1ab23456-7c8d-90ef-g123-45hij6789012
verify_email_url * https://v1.api.us.janrain.com/12345678-1234-1234-1234-123456789012/auth-ui/verify-account?client_id=1ab23456-7c8d-90ef-g123-45hij6789012

* The template for these URLs is: https://v1.api.<region>.janrain.com/<customer-id>/auth-ui/<endpoint>?client_id=<oidc-client-id>.

In order for Hosted Login to function, a few more settings must be added to this login client:

Setting Name Example Value
default_flow_name hosted_login_standard
default_flow_version 20190808194524428311
legal_acceptance_id_1 terms_of_use_v1
legal_acceptance_id_2 privacy_policy_v1
regex_standard_newPassword .*

Step 7: Call Hosted Login from Your Site/App

Note: There are many OpenID Connect libraries available for use depending on the platform or code of your application. The following examples demonstrate the mechanics of OIDC interactions; however it is recommended that you use a library rather than build from scratch.

Login/Registration

When an end user clicks a login/registration action element on your site or /app (e.g., a Login button), you must make a call to the /login/authorize endpoint to display the Akamai-hosted login page to the user.

The following implementation assumes you’re using a public OIDC client along with PKCE (Proof Key for Code Exchange). This is the recommendation for all end-user facing applications.

Request Template

https://v1.api.<region>.janrain.com/<customer-id>/login/authorize?
client_id=<oidc-client-id>
&redirect_uri=<redirect-uri>
&scope=<oidc-scopes>
&response_type=code
&state=<randomly-generated-state-token>
&code_challenge=<client-generated-string-hashed-and-encoded>
&code_challenge_method=<hashing-algorithm>

Example Request

https://v1.api.us.janrain.com/12345678-1234-1234-1234-123456789012/login/authorize?
client_id=1ab23456-7c8d-90ef-g123-45hij6789012
&redirect_uri=https://mydomain.com
&scope=openid profile email phone
&response_type=code
&state=3bd5262737237ef4a
&code_challenge=RTg4QjMyRUJCNzdBRTQ1MkM2NTAzRTVDOEQ5OTg3QjIwMjVBNTcxQTU5RTJFNDYwMzJBQjYxRkM4NjQ0QzdBNw
&code_challenge_method=S256

Making the /login/authorize call displays the Akamai-hosted login page, where the user can sign in or create an account. For example:

Upon successful sign in or account creation, a redirect URI is returned to the app or browser.

Example Redirect URI

https://v1.api.us.janrain.com/12345678-1234-1234-1234-123456789012/login/code?
state=security_token%3bd5262737237ef4a
&%url%https://mydomain.com
&code=4JR27W91a-ofgCe9ur2m6bTghy77

Exchange Code for Token

Send the authorization code (the code from the redirect URI) to the /login/token endpoint, which exchanges that code for an access token, an identity token, and a refresh token.

The following implementation assumes you’re using a public OIDC client along with PKCE (Proof Key for Code Exchange). This is the recommendation for all end-user facing applications.

Request Template

curl -X POST \
  https://v1.api.<region>.janrain.com/<customer-id>/login/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \>
  -d 'grant_type=authorization_code
    &client_id=<oidc-client-id>
    &redirect_uri=<redirect-uri>
    &code=<code-returned-by-authorize-endpoint>
    &code_verifier=<original-client-generated-string>'

Example Request

curl -X POST \
  https://v1.api.us.janrain.com/12345678-1234-1234-1234-123456789012/login/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code
    &client_id=1ab23456-7c8d-90ef-g123-45hij6789012
    &redirect_uri=https%3A%2F%2Fmydomain.com
    &code=4JR27W91a-ofgCe9ur2m6bTghy77
    &code_verifier=AdleUo9ZVcn0J7HkXOdzeqN6pWrW36K3JgVRwMW8BBQazEPV3kFnHyWIZi2jt'

Example Response

{
  "access_token": "X81Pavwil2IhA75ayAK7XLObKHKVUr7vPbAMtCEnagpY9JLRyMqgd_6hquxjdUZ4",
  "refresh_token": "SY5kZY6HPls2KWDM6jHhzYruQaNSmi_eS00PeftLgtsdHxPMlxsAbJ5WMN1MRGON",
  "expires_in": 3600,
  "token_type": "Bearer",
  "scope": "email openid phone profile",
  "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjlhYmM1N2ZmNGEwNzllNWY5NGQxZTUzZmRjYzZjZWZmMGNhNTM1Z
TUiLCJ0eXAiOiJKV1QifQ.eyJhdF9oYXNoIjoiY3lXUmxXcGlnT1VoNXJGRm5aY25ydyIsImF1ZCI6WyIzMmU1ZDEzYi0zMj
c3LTRmMDUtYTk3OC1hNmJiNzZlZTM3ZDkiXSwiYXV0aF90aW1lIjoxNTY1NjQ3ODk2LCJleHAiOjE1NjU2NTI1NTUsImdsb2
JhbF9zdWIiOiJjYXB0dXJlLXYxOi8vZGV2LWFwcC5qYW5yYWluY2FwdHVyZS5jb20vNnR1cWFodTlqN2Z1bXlla2ZnOXV4ZH
A1d3kvdXNlci9kODNiNGYwNS05N2FiLTQ1YjAtYjFlMC01MDcxZGQ1ODE2ZGQiLCJpYXQiOjE1NjU2NDg5NTUsImlzcyI6Im
h0dHBzOi8vdjEuYXBpLnVzLmphbnJhaW4uY29tLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9sb2dpbi
IsImp0aSI6IjdPS1Z0MkEybzl3bnlDaUtFZUFJUzk5TyIsIm5vbmNlIjoibjZuaWZod2FnOTkiLCJzdWIiOiJkODNiNGYwNS
05N2FiLTQ1YjAtYjFlMC01MDcxZGQ1ODE2ZGQifQ.FVtvQbHPrJGspbUW51vemB0rfgaHh7f2h6oooVhSPSSRhOd-gq68GnS
1XcrUJ97vvQUH6_mBpoBZFvKXYO0zJ_MT7H4fFcxe8RlEEUEbp_Wmjd1078IPwaa9xZ4LBeizKQ5EYALIMryASg2cy4Q7Bfs
heEbdvi43dEgYkOYe_5boUcfH32EWq86adM3cz8P_UdUMHWOpToFnkwQQeNWx5O9IFXJ-ITW4RGl2c6sZCrtL2RHpyK7KEav
HAzrKxtdvB5rVL25WDUJKyID7zsiH4VDhifvMH4qRJePa93491YOo50CLyqmkdHqU5DKsjb_rttcd5xxYkPeGvCqRgAzFbg"
}

Learn more about tokens by reading the article OpenID Connect Token Reference.

View/Update User Profile

After the user has an active session, provide a profile action element on your site/app (for example, a My Profile button). When the user clicks the action element, make a call to the /auth-ui/profile endpoint to display the Akamai-hosted profile page to the user.

Request Template

https://v1.api.<region>.janrain.com/<customer-id>/auth-ui/profile?client_id=
<oidc-client-id>

Example Request

https://v1.api.us.janrain.com/12345678-1234-1234-1234-123456789012/auth-ui/profile?
client_id=1ab23456-7c8d-90ef-g123-45hij6789012

Making the /auth-ui/profile call displays the Akamai-hosted profile page. For example:

Note that each of the three sections from the profile landing page can be called directly, if desired, by modifying the endpoint:

User Profile Section Endpoint URL
Personal Data .../auth-ui/profile/data
Account Security .../auth-ui/profile/security
Privacy Settings .../auth-ui/profile/privacy

Step 8: Create CNAMEs

There are three Akamai Identity Cloud domains you can CNAME to match your company domain names. You must reach out to your Identity Cloud representative to start this process.

Domain Default Value Customization

Hosted Login base URL

This domain is used by all Hosted Login implementations.

https://v1.api.us.janrain.com

This domain be CNAMEd to the following subdomain (replacing mycompany with your real domain):

Capture application Registration Domain

This domain is used only if you are using social login.

https://mycompany.us.janraincapture.com

This domain appears in a message to the user after successful social authentication. For example:

"Redirecting to https://mycompany.us.janraincapture.com/widget/token_url.”

The Registration domain can be CNAMEd to the following subdomain:

https://profiles.mycompany.com

Engage application URL

This domain is used only if you are using social login.

https://my-company.rpxnow.com

This domain might appear to the user within a social login identity provider’s webview, depending on the IdP. For example:

"Sign in to my-company.rpxnow.com with your Yahoo ID.”

The Engage application domain can be CNAMEd to the following subdomain:

https://social.mycompany.com