copyright | lastupdated | keywords | subcollection | ||
---|---|---|---|---|---|
|
2019-11-22 |
custom identity provider, authorization, bring your own idp, proprietary idp, legacy idp, oauth, oidc, authentication, oatuh, app security |
appid |
{:external: target="_blank" .external} {:shortdesc: .shortdesc} {:screen: .screen} {:pre: .pre} {:table: .aria-labeledby="caption"} {:codeblock: .codeblock} {:tip: .tip} {:note: .note} {:important: .important} {:deprecated: .deprecated} {:download: .download}
{: #custom-auth}
You can use your own custom identity provider when you are authenticating. Your identity provider can conform to any authentication mechanism alternate to those supported by {{site.data.keyword.appid_full}}, including proprietary or legacy. {: shortdesc}
{: #custom-auth-overview}
By bringing your own identity provider, you can create a custom authentication flow that uses your own protocols. You have more control, such as information that you want to share or information that is stored. {: shortdesc}
Be sure to configure your custom provider before you add it to your application. {: tip}
{: #custom-auth-when}
When {{site.data.keyword.appid_short_notm}} does not provide direct support for a particular identity provider, you can use the custom identity flow to bridge the authentication protocol to {{site.data.keyword.appid_short_notm}}'s existing authentication flow. For example, you want to use GitHub or LinkedIn to allow your users to sign in. You can use the identity provider's existing SDK to facilitate user authentication information before packaging and exchanging it with {{site.data.keyword.appid_short_notm}}.
There are many scenarios where a different authentication flow is necessary:
- Proprietary, in-house identity providers
- Third-party identity providers
- Complicated authentication flows, which can include proprietary multi-factor mechanisms
Occasionally, a legacy provider might use their own custom authentication protocol. Because the custom identity flow completely decouples authentication from authorization, you can adopt any authentication mechanism of your choice and then provide the resulting authentication information to {{site.data.keyword.appid_short_notm}}. All without exposing user credentials.
{: #custom-auth-tech}
The custom identity workflow is built on the JWT-Bearer extension grant type that is defined in Assertion Framework for OAuth 2.0 Authorization Grants [RFC7521]. In order to exchange user information for {{site.data.keyword.appid_short_notm}} tokens, your authentication architecture creates a trust relationship with {{site.data.keyword.appid_short_notm}} by using an asymmetric RSA key pair. Once trust is established, you can use the JWT-Bearer grant type to exchange verified user information within a signed JWT for {{site.data.keyword.appid_short_notm}} tokens.
{: #custom-auth-flow}
As with all authentication flows, custom identity requires that the application is able to establish a degree of trust with {{site.data.keyword.appid_short_notm}} to ensure the integrity of identity provider user information. Custom identity employs an asymmetric RSA public and private key pair to establish its trust relationship. Depending on your architectural requirements, custom identity supports two trust models that differ only in the storage location and usage of the private key.
{: caption="Figure 1. The request flows for custom authentication" caption-side="bottom"}
- 1. Identity provider signed
- Just as with traditional OAuth 2.0 flows, the most secure trust model creates a relationship between your identity provider and authorization server; in this case {{site.data.keyword.appid_short_notm}}) directly. Under this model, your identity provider is responsible for storing the private key and signing JWT assertions. When passed to {{site.data.keyword.appid_short_notm}}, these assertions are validated with the matching public key, which ensures that the user information from your identity provider was not maliciously altered during transport.
- 2. Application signed
- Alternatively, you can base your trust model on the relationship between your app and {{site.data.keyword.appid_short_notm}}. In this workflow, your private key is stored in your server-side application. After a successful authentication, your app is responsible for converting the identity providers response into a JWT and signing it with its private key before the app sends the token to {{site.data.keyword.appid_short_notm}}. Since this identity provider has no relationship with {{site.data.keyword.appid_short_notm}}, this architecture creates a weaker trust model. Although {{site.data.keyword.appid_short_notm}} can trust the information that is sent by the server-side application, it cannot be certain the data was the original sent by the identity provider.
{: #generating-jwts}
You can convert your verified user data to a custom identity JWT by generating a JSON web token{: external}. The token must be signed with the private key that matches your preconfigured public key. For a list of token signing libraries, check out https://jwt.io/{: external}. {: shortdesc}
{: #jwts-example}
Token header:
{
"alg": "RS256",
"typ": "JOSE"
}
{: screen}
Token payload:
{
// Required
"iss": "String", // Should reference your identity provider
"aud": "String", // Must be the OAuth server URL name
"exp": "Int", // Should be a value with a short lifespan
"sub": "String", // Must be the unique user ID provided by your identity provider
// Normalized claims (optional)
"name": "String",
"email": "String",
"locale": "String",
"picture": "String",
"gender": "String"
// Custom Scopes to add to access token (optional)
scope="custom_scope1 custom_scope2"
// Other custom claims (optional)
role="admin"
}
{: screen}
Field | Description |
---|---|
iss |
Should contain a reference to your identity provider. |
aud |
The OAuth server URL. Format: `https://{region}.appid.cloud.ibm.com/oauth/v4/{tenantId}`. |
exp |
The length of time that the token is valid. For security reasons, it should have a short life span and be specific. |
sub |
The unique user ID that is provided by the identity provider. |
Normalized claims | All [normalized claims](/docs/services/appid?topic=appid-tokens) are provided in the identity token that is returned in response to this request. More custom claims can be found by using the [`/userinfo` endpoint](/docs/services/appid?topic=appid-profiles). |
Scope | By default, all {{site.data.keyword.appid_short_notm}} tokens contain a group of preset scopes. You can request extra scopes by doing one of the following:
|
{: #exchanging-jwts}
To create the bridge between your custom provider and {{site.data.keyword.appid_short_notm}}, you need to have {{site.data.keyword.appid_short_notm}} tokens. To obtain service tokens, exchange your verified user information by using the /token
endpoint{: external}.
{: shortdesc}
Post /token
Content-Type: application/x-www-from-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
assertion=<payload>
scope="<space separated scope array>"
{: codeblock}
Variable | Description |
---|---|
Content-type | applications/x-www-from-urlencoded |
grant_type | urn:ietf:params:oauth:grant-type:jwt-bearer |
assertion | A JWS payload string. |
scope | A white space separated list of your custom scopes. |