IBM Cloud Docs
Web apps

Web apps

When you are developing a web application, you can use the IBM Cloud® App ID web flow to securely authenticate users. Users are then able to access your server-side protected content in your web apps.

Understanding the flow

Web apps often require users to authenticate to access protected content. App ID uses the OIDC authorization code flow to securely authenticate users. With this flow, when the user is authenticated, the app receives an authorization code. The code is then exchanged for an access, identity, and refresh token. In code, exchange step the tokens are always sent by using a secure backchannel between the app and the OIDC server. This process provides an extra layer of security as the attacker is not able to intercept the tokens. These tokens can be sent directly to the web server hosting application for user authentication.

App ID web app request flow
App ID web app request flow

  1. A user initiates the authorization flow by sending a request to the /authorization endpoint via the App ID SDK or API.

  2. If the user is unauthorized, the authentication flow is started with a redirect to App ID.

  3. Depending on the user's /authorization request parameters or identity provider configuration, it starts the Login Widget in the user's browser.

  4. The user chooses an identity provider to authenticate with and completes the sign-in process.

  5. The identity provider redirects to the client app with the authorization code.

  6. The App ID SDK exchanges the authorization code for access, identity, and optional refresh tokens from the App ID service.

  7. The tokens are saved by the App ID SDK and a redirect to the client application occurs.

  8. The user is granted access to the app.

Configuring the Node.js SDK

You can configure App ID to work with your Node.js web applications.

Before you begin

You must have the following prerequisites:

  • An instance of the App ID service
  • A set of service credentials
  • NPM version 4 or higher
  • Node version 6 or higher
  • Your redirect URI set in the App ID service dashboard

Check out the following video to learn about protecting Node applications with App ID. Then, try it out yourself by using a simple Node sample app.

Installing the Node.js SDK

  1. By using the command line, change to the directory that contains your Node.js app.

  2. Install the App ID service.

    npm install --save ibmcloud-appid
    

Initializing the Node.js SDK

  1. Add the following require definitions to your server.js file.

    const express = require('express');
    const session = require('express-session')
    const passport = require('passport');
    const WebAppStrategy = require("ibmcloud-appid").WebAppStrategy;
    const CALLBACK_URL = "/ibm/cloud/appid/callback";
    
  2. Set up your express app to use express-session middleware.

    const app = express();
    app.use(session({
       secret: "123456",
       resave: true,
       saveUninitialized: true
    }));
    app.use(passport.initialize());
    app.use(passport.session());
    

    You must configure the middleware with the proper session storage for production environments. For more information, see the express.js.

  3. Obtain your credentials in one of the following ways.

    • By navigating to the Applications tab of the App ID dashboard. If you don't have an application in the list, you can click Add application to create a one.

    • By making a POST request to the /management/v4/<tenantId>/applications endpoint.

      Request format:

      curl -X POST \  https://us-south.appid.cloud.ibm.com/management/v4/39a37f57-a227-4bfe-a044-93b6e6060b61/applications/ \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer <IAMToken>' \
      -d '{"name": "ApplicationName"}'
      

      Example response:

      {
      "clientId": "111c22c3-38ea-4de8-b5d4-338744d83b0f",
      "tenantId": "39a37f57-a227-4bfe-a044-93b6e6060b61",
      "secret": "ZmE5ZDQ5ODctMmA1ZS00OGRiLWExZDMtZTA1MjkyZTc4MDB4",
      "name": "ApplicationName",
      "oAuthServerUrl": "https://us-south.appid.cloud.ibm.com/oauth/v4/39a37f57-a227-4bfe-a044-93b6e6060b61"
      }
      
  4. Optional: Decide how to format your redirect URI. The redirect can be formatted in two different ways.

    • Manually in a new WebAppStrategy({redirectUri: "...."})
    • As an environment variable named redirectUri

    If neither are provided, the App ID SDK tries to retrieve the application_uri of the app that is running on IBM Cloud and append a default suffix /ibm/cloud/appid/callback.

  5. By using the information obtained in the previous steps, initialize the SDK.

    passport.use(new WebAppStrategy({
    tenantId: "<tenantID>",
    clientId: "<clientID>",
    secret: "<secret>",
    oauthServerUrl: "<oauthServerURL>",
    redirectUri: "<appURL>" + CALLBACK_URL
    }));
    
  6. Configure passport with serialization and deserialization. This configuration step is required for authenticated session persistence across HTTP requests. For more information, see the passport docs.

    passport.serializeUser(function(user, cb) {
       cb(null, user);
       });
    passport.deserializeUser(function(obj, cb) {
       cb(null, obj);
       });
    
  7. Add the following code to your server.js file to issue the service redirects.

    app.get(CALLBACK_URL, passport.authenticate(WebAppStrategy.STRATEGY_NAME));
    
  8. Register your protected endpoint by adding the following code snippet into your app.js file.

    app.get(‘/protected_resource’, passport.authenticate(WebAppStrategy.STRATEGY_NAME), function(req, res) {res.json(req.user); });
    

For more information, see the App ID Node.js GitHub repository.

Configuring the Liberty for Java SDK

You can configure App ID to work with your Liberty for Java web applications.

Before you begin

You must have the following prerequisites:

  • An instance of the App ID service
  • A set of service credentials
  • Apache Maven 3.5 or higher
  • Java 1.8
  • A Liberty for Java web application

Check out the following video to learn about protecting Liberty for Java applications with App ID. Then, try it out yourself by using a simple Liberty for Java sample app.

Installing the Liberty for Java SDK

  1. Add an OpenID Connect feature to your server.xml.

    <featureManager>
       <feature>ssl-1.0</feature>
       <feature>appSecurity-2.0</feature>
       <feature>openidConnectClient-1.0</feature>
    </featureManager>
    
  2. Obtain your credentials in one of two ways.

    • By navigating to the Applications tab of the App ID dashboard. If you don't already have one, you can click Add application to create a new one.

    • By making a POST request to the /management/v4/<tenantID>/applications endpoint.

      Request format:

      curl -X POST \  https://us-south.appid.cloud.ibm.com/management/v4/39a37f57-a227-4bfe-a044-93b6e6060b61/applications/ \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer <IAMToken>' \
      -d '{"name": "ApplicationName"}'
      

      Example response:

      {
      "clientId": "111c22c3-38ea-4de8-b5d4-338744d83b0f",
      "tenantId": "39a37f57-a227-4bfe-a044-93b6e6060b61",
      "secret": "ZmE5ZDQ5ODctMmA1ZS00OGRiLWExZDMtZTA1MjkyZTc4MDB4",
      "name": "ApplicationName",
      "oAuthServerUrl": "https://us-south.appid.cloud.ibm.com/oauth/v4/39a37f57-a227-4bfe-a044-93b6e6060b61"
      }
      
  3. Create an Open ID Connect Client feature and define the following placeholders. Use the service credentials to fill the placeholders.

    <openidConnectClient
       clientId='{{site.data.keyword.appid_short_notm}} client_ID'
       clientSecret='{{site.data.keyword.appid_short_notm}} Secret'
       authorizationEndpointUrl='oauthServerUrl/authorization'
       tokenEndpointUrl='oauthServerUrl/token'
       jwkEndpointUrl='oauthServerUrl/publickeys'
       issuerIdentifier='Changed according to the region'
       tokenEndpointAuthMethod="basic"
       signatureAlgorithm="RS256"
       authFilterid="myAuthFilter"
       trustAliasName="ibm.com"
    />
    
    OIDC element variables for Liberty for Java apps
    Component Description
    clientID
    secret
    oauth-server-url
    Complete step two to obtain your service credentials.
    authorizationEndpointURL Add /authorization to the end of your oauthServerURL.
    tokenEndpointUrl

    Add /token to the end of your oauthServerURL.

    jwkEndpointUrl Add /publickeys to the end of your oauthServerURL.
    issuerIdentifier The issuer identifier takes the following form: &lt;region>&gt;.cloud.ibm.com. Learn more about the available regions.
    tokenEndpointAuthMethod Specified as "basic".
    signatureAlgorithm Specified as "RS256".
    authFilterid The list of resources to protect.
    trustAliasName The name of your certificate within your truststore.

Initializing the Liberty for Java SDK

  1. In your server.xml file, define an authorization filter to specify protected resources. If a filter is not defined, the service protects all resources.

    <authFilter id="myAuthFilter">
       <requestUrl id="myRequestUrl" urlPattern="/protected_resource" matchType="contains"/>
    </authFilter>
    
  2. Define your special subject type as ALL_AUTHENTICATED_USERS.

    <application type="war" id="ProtectedServlet" context-root="/appidSample" location="${server.config.dir}/apps/libertySample-1.0.0.war">
       <application-bnd>
             <security-role name="myrole">
                <special-subject type="ALL_AUTHENTICATED_USERS"/>
             </security-role>
       </application-bnd>
    </application>
    
  3. Download the libertySample-1.0.0.war file from GitHub and place it in your server's apps folder. For example, if your server is named defaultServer, the war file would go here target/liberty/wlp/usr/servers/defaultServer/apps/.

  4. Configure SSL by adding the following to your server.xml file. You also need to create a truststore.

       <keyStore id="defaultKeyStore" password="myPassword"/>
       <keyStore id="appidtruststore" password="Liberty" location="${server.config.dir}/mytruststore.jks"/>
       <ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="appidtruststore"/>
    

By default SSL configuration requires the truststore be configured for OpenID Connect. Learn more about configuring an OpenID Connect Client in Liberty.

Configuring Spring Boot for Java SDK

You can configure App ID to work with your Spring Boot applications.

Before you begin

You must have the following prerequisites:

  • An instance of the App ID service
  • A set of service credentials
  • A Java + Maven project
  • Apache Maven 3.5 or higher
  • Java 1.8
  • Spring Boot 2.0 and Security OAuth 2.0 or higher

Initializing the Spring Boot framework

  1. Add the following code between the <project> </project> tags in your Maven pom.xml file.

    <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.0.2.RELEASE</version>
       <relativePath/>
    </parent>
    
  2. Add the following dependencies to your Maven pom.xml file.

    <dependencies>
       <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
       </dependency>
       <dependency>
             <groupId>org.springframework.security.oauth.boot</groupId>
             <artifactId>spring-security-oauth2-autoconfigure</artifactId>
             <version>2.0.0.RELEASE</version>
       </dependency>
    </dependencies>
    
  3. In the same file, include the Maven plug-in.

    <plugin>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    

Initializing OAuth2

  1. Add the following annotations to your Java file.

    @SpringBootApplication
    @EnableOAuth2Sso
    
  2. Extend the class with WebSecurityConfigurerAdapter.

  3. Override any security configuration and register your protected endpoint.

       @Override
       protected void configure(HttpSecurity http) throws Exception {
          http.authorizeRequests()
                   .antMatchers("/protected_Resource").authenticated()
                   .and().logout().logoutSuccessUrl("/").permitAll();
       }
    

Adding credentials

  1. Obtain your credentials in one of the following ways.

    • By navigating to the Applications tab of the App ID dashboard. If you don't already have one, you can click Add application to create a new one.

    • By making a POST request to the /management/v4/<tenantID>/applications endpoint.

      Request format:

      curl -X POST \  https://us-south.appid.cloud.ibm.com/management/v4/39a37f57-a227-4bfe-a044-93b6e6060b61/applications/ \
      -H 'Content-Type: application/json' \
      -H 'Authorization: Bearer <IAMToken>' \
      -d '{"name": "ApplicationName"}'
      

      Example response:

      {
      "clientId": "111c22c3-38ea-4de8-b5d4-338744d83b0f",
      "tenantId": "39a37f57-a227-4bfe-a044-93b6e6060b61",
      "secret": "ZmE5ZDQ5ODctMmA1ZS00OGRiLWExZDMtZTA1MjkyZTc4MDB4",
      "name": "ApplicationName",
      "oAuthServerUrl": "https://us-south.appid.cloud.ibm.com/oauth/v4/39a37f57-a227-4bfe-a044-93b6e6060b61"
      }
      
  2. Add an application.yml configuration file to the /springbootsample/src/main/resources/ directory. You can complete your configuration with the information from your service credentials.

    security:
    oauth2:
       client:
       clientId: <clientID>
       clientSecret: <clientSecret>
       accessTokenUri: <oauthServerURL>/token
       userAuthorizationUri: <oauthServerURL>/authorization
       resource:
       userInfoUri: <oauthServerURL>/userinfo
    

Using App ID with other languages

With an OIDC-compliant client SDK, you can use App ID with other languages. Check out the list of certified libraries for more information.

Next steps

With App ID installed in your application, you're almost ready to start authenticating users! Try doing one of the following activities next: