You are on page 1of 8

API Connect — Using custom hooks in

Dev Portal to share application


credentials with Identity Provider

Overview

This article describes how to use custom hooks in the API Connect
v2018. Developer Portal to share application credentials with
Identity Provider (IdP) like IBM Security Access Manager.

It is common in enterprise that they have existing IdP that handles


API Security like OAuth and OIDC. Applications needs to interact
with these Enterprise IDP to obtain access tokens or id tokens before
calling APIs published in APIC gateway. Applications need to
provide application credentials (client_id and client secret) for this
exchange. In APIC, application credentials are created when an
application developer register their application(s) on the Developer
Portal. Sometimes, there is requirement to share application
credentials created in APIC with existing Enterprise IDP.

To do this, in APIC Developer Portal, this is a custom hook


mechanism that allows you to handle some of these application life
cycle events so that you can “do something” with it. E.g. when an
application is created or when a client_id is reset, we can define
hooks/functions to handle these events.

Before we begin, we need to understand the relationship between


application, credentials, client_id and client_secret.
1. An application have one (1) or up to twenty (20) credentials.
Each application has a unique identifier, app_id. An application
have one or many redirect URLs.

2. Each credential has a pair of client_id and client_secret. It also


has a unique identifier, cred_id; that does not change.

3. The client_id and client_secret can be changed. When you reset


the client_id both the client_id and client_secret are
changed.When you reset the client_id, only the client_secret is
changed.

The following implementation assumes that the IDP provides a set


of REST interfaces that can be used to create, update or delete an
application with its credentials. The IDP should have the following
object model.

 Application object with fields — id, name, redirect_url (comma-


separated)

 Credential object with fields — id, client_id, client_secret,


app_id as foreign key

Custom Hook

The following are a list of custom hooks:

1. modulename_apic_app_create

This hook is called when an application is created. As part of this, a


credential is also automatically created. Therefore, you will need to
send the following information to the
IDP: app_id, cred_id, app_name, redirect_url list, cred_id, client_id, c
lient_secret. The IDP should create an application object, a
credential object and associate the credential object to the
application. It also creates a redirect_url object.

Use the POST method and with the following URL and payload.
POST /apps HTTP/1.1
Host: {idp_hostname}
Accept: application/json
Content-Type: application/json; charset=iso-8859-1{
"id": {app_id},
"name": {app_name},
"title": {app_title},
"credential": {
"id": {cred_id},
"client_id": {client_id},
"client_secret": {client_secret}
}
"redirect_endpoints": [
{redirect_url_1},
{redirect_url_2}
]
}

2. modulename_apic_app_update

This hook is called when an application is updated — where only the


name and the redirect_url is updated. The IDP should update
the name, title and redirect_url of the application object.

Use the PUT method and with the following URL and payload.
PUT /apps/{app_id} HTTP/1.1
Host: {idp_hostname}
Accept: application/json
Content-Type: application/json; charset=iso-8859-1{
"name": {app_name},
"title": {app_title},
"redirect_endpoints": [
{redirect_url_1},
{redirect_url_2}
]
}

3. modulename_apic_app_delete

This hook is called when an application is deleted. The IDP should


delete the application object and all the credential objects by
its app_id.

Use the DELETE method and with the following URL and payload.
DELETE /apps/{app_id} HTTP/1.1
Host: {idp_hostname}

4. modulename_apic_app_clientid_reset

This hook is called when the client_id is reset (together with


the client_secret). The IDP should update the credential object with
new client_id and client_secret.

Use the PUT method and with the following URL and payload.
PUT /apps/{app_id}/credentials/{cred_id} HTTP/1.1
Host: {idp_hostname}
Accept: application/json
Content-Type: application/json; charset=iso-8859-1{
"client_id": {client_id},
"client_secret": {client_secret}
}

5. modulename_apic_app_clientsecret_reset

This hook is called when the client_secret is reset. The IDP should


update the credential object with new client_secret.

Use the PUT method and with the following URL and payload.
PUT /apps/{app_id}/credentials/{cred_id} HTTP/1.1
Host: {idp_hostname}
Accept: application/json
Content-Type: application/json; charset=iso-8859-1{
"client_secret": {client_secret}
}

7. modulename_apic_app_creds_create

This hook is called when a new credential is created for an existing


application. The IDP should create a new credential object and map
it to an existing application object.

Use the POST method and with the following URL and payload.
POST /apps/{app_id}/credentials/{cred_id} HTTP/1.1
Host: {idp_hostname}
Accept: application/json
Content-Type: application/json; charset=iso-8859-1{
"credential": {
"client_id": {client_id},
"client_secret": {client_secret}
}
}

8. modulename_apic_app_creds_delete

This hook is called when the credential is deleted. The IDP should
delete the credential object.

Use the DELETE method and with the following URL and payload.
DELETE /apps/{app_id}/credentials/{cred_id} HTTP/1.1
Host: {idp_hostname}
Accept: application/json
Content-Type: application/json; charset=iso-8859-1

9. modulename_apic_app_creds_update

This hook is called when the title of the credential is updated. The
IDP should update the credential object. This is no need to handle
this because the title of the credential is not important to the IDP.
How to create custom module

1. Create the module

1. Create a folder, say app-push-cred-module. Change directory into


the folder.

2. Create a custom .module file. The name of my module


is app_cred_push.

3. Add the hook function in this .module file. The name of my


module is app_cred_push; so the file name is app_cred_push.module.
This module file is a PHP code.

4. Prefix the function with your custom module name with the
following format moduleName_apic_app_create.
function app_cred_push_apic_app_create($node, $app) {
}

5. Create a info.yaml file in the same folder. The name of my module


is app_cred_push.info.yaml. E.g.
name: App Credentials Push Module
description: Send HTTP request containing application
credentials when it is created or changed.
package: Custom
type: module
version: 1.0
core: 8.x

6. You need to know a bit of PHP to code this. There is a sample


implementation in the Github — https://github.com/khongks/app-
cred-push-module.git.

2. Package the module


1. Package the module using zip or tar to include the folder. From
the folder app-cred-push-module.
? cd ..
? zip -r app-cred-push-module.zip app-cred-push-module

3. Install the module

1. Sign in as admin in the Developer Portal.

2. Go to the Manage > Extend and click on Install new


module.

3. On the Install new module page, choose file and click Install.

4. Click on Enable newly added modules to return to the list


tab for the Extend page.

5. Find your module, check the box and click Enable.

4. Troubleshoot

1. To log into a file, use the following in your PHP code.


\Drupal::logger('app_cred_push')->info('apic_app_create hook
called');

2. To view the logs, ssh into the portal server and run the following:
? sudo -i
? kubectl get poNAME
READY STATUS RESTARTS AGE
apic-portal-apic-portal-db-cljxp 2/2 Running
0 8d
apic-portal-apic-portal-nginx-664c6c5b59-r6pv7 1/1 Running
0 25d
apic-portal-apic-portal-www-q2wdj 2/2 Running
0 8d
ptl-backup-4pjvb-pfvqj 0/1
Completed 0 8d
ptl-backup-662vt-g2rn8 0/1
Completed 0 8d
ptl-backup-p54nf-j4ln7 0/1 Error
0 8d
ptl-list-backups-kvsx8-rn85l 0/1 Error
0 8d
ptl-list-backups-vr5rp-xs9xk 0/1
Completed 0 8d

? kubectl logs apic-portal-apic-portal-www-q2wdj web --tail=1000


-f

3. Ensure that your PHP code can be compiled (no syntax error) —
because it will crash your portal site.

4. If you crash your portal site, you need to correct the error within
the container.
? kubectl -it exec apic-portal-apic-portal-www-q2wdj -c web bash

5. Go to the folder (as follows), edit and correct the error in the file.
? cd
/web/platforms/devportal-8.x-2018.4.1.7-20190910-0421/sites/{org
}.{catalog}.{portal-web-endpoint}/modules/{module-name}

for example:
? cd
/web/platforms/devportal-8.x-2018.4.1.7-20190910-0421/sites/thin
k-provider-organization.test.portal-web.think.org/modules/app-
cred-push-module

You might also like