Sign In Your App Users With Any Identity Provider Using App ID

By: Ishan Gulhane

IBM Cloud App ID’s custom identity flow

Application security is crucial as attackers increasingly target applications to gain access to protected information. A secure application minimizes the likelihood that unauthorized code is able to access, modify, or delete sensitive user data. By integrating IBM Cloud App ID into your apps, you can easily add authentication and authorization to secure your apps and protected resources—even when you don’t have a lot of security experience.

App ID provides out-of-the-box authentication support for social identity providers (IdPs), such as Google and Facebook. Additionally, it makes integrating App ID with other IdPs simple and straightforward. This is useful in many scenarios where you might have custom or proprietary authentication mechanisms or another IdP which is not part of the IdPs that App ID supports out of the box. In these cases, you can bridge the gap between your app’s authentication mechanism and the service by using App ID’s custom identity flow.

In this blog post, I’ll explain App ID’s custom identity flow and walk you through an example of how you can use it to integrate a third-party identity provider with App ID—specifically, LinkedIn.

What is custom identity?

With custom identity, app developers can create a custom authentication flow that uses their own custom protocol.

The custom identity workflow is built on the JWT-Bearer extension grant type that is defined in the Assertion Framework for OAuth 2.0 Authorization Grants. In order to exchange user information for App ID tokens, your authentication architecture creates a trust relationship with App ID by using an asymmetric RSA key pair.

After trust is established, you can exchange verified user information with App ID access and identity tokens. Access tokens represent authorization and can be used to retrieve the backend resources that are protected by authorization filters set by App ID. Identity tokens represent authentication and contain information about the user.

Depending on your architectural requirements, custom identity supports two trust models that differ in the storage location and usage of the private key. In this post, I’ll focus on the application signed trust model as it’s the most flexible with regard to the identity provider.

What is custom identity?

In the application signed model, a server-side component is required to securely house and control access to a private key. After a successful authentication, your app is responsible for converting the identity providers response into an App ID-compliant JWT and signing it with its private key before the app sends the token to App ID by using the /token endpoint.

The private/public key pair that the app uses to sign the JWT is generated during a setup phase by the app, and the public key is registered with App ID. This allows App ID to verify the signed JWT it receives and ensure that the data was sent by the app and was not modified in transit.

After App ID verifies the signature and the various claims within the JWT, it generates and returns the corresponding App ID access and identity tokens.

Using custom identity with LinkedIn

Before we get started, let’s review at what the flow between your app, LinkedIn, and App ID will look like. During the setup phase, you first generate an RSA public key pair and configure your App ID instance with the public key. Then, as shown in the diagram, your app goes through the following steps at runtime:

  1. A user initiates the sign in flow through the app.

  2. The application redirects the user to the LinkedIn login page.

  3. The user signs in by using their LinkedIn credentials.

  4. On successful sign in, LinkedIn sends an access token and user information to the application.

  5. The application creates a signed JWT and then sends it to App ID.

  6. App ID exchanges the JWT for access and identity tokens.

  7. The application can now use the App ID tokens to access a protected resource or make business decisions.

The application can now use the App ID tokens to access a protected resource or make business decisions.

Configuring sign in

Before getting started, be sure that you have the following prerequisites:

Creating application RSA PEM key pair

  1. Generate an RSA PEM key pair by using Open SSL.

    openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
    openssl rsa -pubout -in private_key.pem -out public_key.pem

Configuring your App ID application credentials

  1. Navigate to the Applications tab in your App ID dashboard and click Add application to create new credentials. Generate your credentials and click save.

  2. Click View credentials and copy the credentials. The sample app uses this information in the configuration.
    View credentials

  3. Navigate to the Identity Providers > Manage tab and enable custom identity.

  4. Navigate to the Custom Identity tab and save the recently generated public key.
    Custom Identity

Setting up LinkedIn

  1. Log in to the developer portal, and click My Apps.

  2. Click Create Application and enter the details about your app.

  3. Select the newly created app and click the Auth tab. Enter the following URL in the Redirect URLs field present in OAuth 2.0 settings: http://localhost:4000/auth/linkedin/callback.
    Auth

  4. Copy the Client ID and secret from Application credentials. The sample app uses this information in the configuration.
    Application credentials

Setting up the sample application

  1. Download the application.

  2. In an editor, open the app.js file and make the following changes.

    • Use the credentials that you created in the first step to update the config variable.

      const config = {
       "clientId": "clientId",
       "oauthServerUrl": "oauthServerUrl",
       "profilesUrl": "profilesUrl",
       "secret": "secret",
       "tenantId": "tenantId",
       "preferredLocale": "en"
      };
    • Replace the following variables with your LinkedIn application credentials.

      const LINKEDINCLIENTID = "LINKEDINCLIENTID";
      const LINKEDINSECRET = "LINKEDINSECRET";
  3. Update the resources > private.pem file with your newly generated private key.

  4. Create and configure a custom payload for a signed JSON Web Token by using the following example as a guide.
    let sampleToken = {
    header: {
                alg: 'RS256',
                kid: 'sample-rsa-private-key'
                },
    payload: {
                iss: profile.provider,
                sub: profile.id,
                aud: tokenManager.serviceConfig.getOAuthServerUrl().split('/')[2],
                exp: 9999999999,
                scope: 'customScope'
                }
    };
    Object.assign(sampleToken.payload, profile._json);
    const generateSignedJWT = (privateKey) => {
    const { header, payload } = sampleToken;
    return jwt.sign(payload, privateKey, { header });
    };
    const privateKey = fs.readFileSync('./resources/private.pem');
    let jwsTokenString = generateSignedJWT(privateKey);
  5. Configure your application to obtain App ID tokens by using the following example as a guide.
    const tokenManager = new appID.TokenManager(config);
    tokenManager.getCustomIdentityTokens(jwsTokenString).then((authContext) => {
                req.session[APPID_AUTH_CONTEXT] = authContext;
                req.session[APPID_AUTH_CONTEXT].identityTokenPayload = jwt.decode(authContext.identityToken);
                req.session[APPID_AUTH_CONTEXT].accessTokenPayload = jwt.decode(authContext.accessToken);
                next();
    }).catch((error) => {
                res.redirect('/error');
    });

Running the sample application

  1. Configure NPM by running the following commands.

    npm install
    npm start
  2. Load the web application in a browser by using the link http://localhost:4000.
    Running the sample application

  3. Click Sign in with LinkedIn and enter your sign-in credentials to start the authentication process.
    Sign in with LinkedIn

  4. After successful authentication and authorization, a user is routed to a protected page that contains the tokens payload and user information that is sent by App ID.
    App ID

You’ve learned how to use the custom identity flow to integrate LinkedIn with App ID in your app configuration using a sample! Now you can try using the custom identity flow to integrate your own identity provider.

Have questions or feedback?

As always, we’d love to hear your feedback and questions. Get help for technical questions at Stack Overflowwith the ibm-appid tag. For non-technical questions, use IBM developerWorks with the appid tag. For defect or support needs, use the Support section in the IBM Cloud menu. To get started with App ID, check it out in the IBM Cloud Catalog. For more articles on App ID, check out IBM Cloud App ID archives here.

Be the first to hear about news, product updates, and innovation from IBM Cloud