Implementing OAuth using webMethods Integration Server

webMethods Digital Business Platform’s Integration Server supports OAuth 2.0. The Integration Server (IS) can be used as an OAuth client, an authorization server, or a resource server. This post describes how to use OAuth 2.0 with Integration Server.

Integration Server supports four types of OAuth grant types –

1. Authorization Code Grant
2. Client Credentials Grant
3. Implicit Grant
4. Resource Owner Password Credentials Grant

AUTHORIZATION CODE GRANT TYPE (Recommended)

Theoretical Knowledge

The authorization code grant type is used to authenticate and provide access to clients that are registered on the authorization server (Here our Integration Server is acting as an Authorization server as well).

This grant type requires the claiming client to authenticate to the authorization server before obtaining an access token and provides access to confidential and public clients.

When using the authorization code grant type, the authorization server can issue a refresh token to the registered client application along with the access token.
A refresh token enables clients to get a new access token without requesting additional approval from the resource owner. When the access token expires, the client application can use the pub.oauth:getToken(replaced by now depreciated getAccessToken) service to pass the refresh token to the authorization server to request a new access token.

Practical Knowledge

Step 1 - Client Configuration:

A client must register himself and obtain client_id from the integration server. In the IS console go to Security->OAuth->Client Registration page and click on ‘Register Client’. Enter the information as shown below. Redirect URL should be the URL, where IS will redirect the page after authorizing the request. I have created a simple RESTful service on the IS as a redirect URL.

Remember that the Client ID will be generated when you click Save Changes. Please note that in order to get the client secret generated for your client. Please select the type as ‘Confidential’ from the drop down menu.

image

Your client will use this ‘Client ID’ to authorize himself and request an access token.

Step 2 - Scope Management:

The scope indicates the resources the client can access on behalf of resource owner. You need to indicate one or more folders or services on the IS in the scope. Once a client is granted access to a scope, he can access the folders and services included in that scope.

Go to Security->Oauth->Scope Management page and click on ‘Add Scope’. Once the page is open, mention the scope details as shown below

Here I have created a simple calculator API for demonstration purpose and included it’s

a. Fully qualified name of the calculator flow service.
b. Resource path mapped to it in the REST descriptor service i.e. - /oauth2/calculate
c. And the package name it is residing in(Optional, and to be done only if you want to include other services residing in the same package also to have the same scope).

image

image

Once the scope is added, map the scope with the client using the Associate Scope to Clients nested option in the Scope Management option in OAuth.

image

Once this setup is done your client is ready to request for the access token to Authorization Server.

Step 3 - Authorization Code Generation

Requesting token for authorization code approach is a 2-step process. In the first step, the client authorizes himself with the authorization server using pub.oauth:authorize service and receives the authorization code. Once the authorization code is received, it can be used to obtain the access token using pub.oauth:getToken service.

When the client initiates the pub.oauth:authorize request, it brings up a page for the resource owner to either approve the access request or reject it.

image

Step 4 - Access Token

When the resource owner approves the request, the integration server generates the authorization code and redirects the page to the ‘redirect URL’ specified in the client configuration.

The service hosted at redirect URL passes the authorization code to pub.oauth:getToken service to exchange authorization code for an access token as shown below.

image

Integration Server administrator can verify all the tokens in the IS console.

image

The client application can use the token as a bearer token to access the resource on the server i.e. to run the calculator API in my case.

For other grant types, please note the below mentioned points -

1. Refer to POC package zzUdish and go through the flow code of wrapper services placed in fully qualified paths mentioned below for respective grant types -

a. zzUdish.rs.oauth2_.services:genClientCredsToken - Client Configuration (Scope is same as above)

b. zzUdish.rs.oauth2_.services:genImplicitToken - Client Configuration (Scope is same as above)

c. zzUdish.rs.oauth2_.services:genROPCToken - Client Configuration (Scope is same as above)

2. Refer to POC folder zzUdish.services for core services used for implementing Authorization Code and Implicit Grant Types respectively.

3. Please note that an explicit ACL access needs to be provided for following grant types only - Client Credentials and Resource Owner Password Credentials(ROPC).

------ To do this, First go to Security > User Management and add the client id as the user (if it did not get created implicitly upon client creation) and then add this user to an existing user group or create a new user group depending on your access requirement.

------ Now, go to Security > ACLs and assign the Administrators ACL or custom ACL created by you, to the user group created in 3.1. as per your access requirements.

-----------------------------------------------------------------------------

Important Points to Ponder

  1. Here, we have invoked pub.oauth:getToken inbuilt service via pub.client:http invoke step in a flow service. This approach can be customised conforming to the solution design for a particular application.

  2. There is a provision to skip the approval page & approving every incoming access token generation request by default. It is possible. Although, it is not recommended but, if the requirement demands then one can use - wm.server.outh:approve service with isApproved Boolean value hardcoded as ‘true’ along with other input field values.
    Please note that this service has to be invoked via pub.client:http invoke step only & cannot be used as a standalone invocation via Integrated Development Environment(IDE).

  3. Use pub.oauth:introspectToken service to check the token expiry.

  4. wm.server.outh:approve service is invoked as a listener of that Approve button on the dynamic server page as depicted in Figure 6.

  5. In order for Integration Server to log OAuth activity, the Security logger must be enabled and configured to log the following security areas: Authentication and Authorization.

Please feel free to reach out in the comments. Thank you.

zzUdish.zip (61.8 KB)

14 Likes

Very Informative. Nice work @ukumar029.

Thank you @saunav20 :slight_smile:

Hi Everyone! Please hit a like and comment on this topic if you enjoyed reading it. It would really help to outgrow its reach and help millions like yourself in this community to gain knowledge of this topic.
Many Thanks again for spending your valuable time and visiting the topic.
Keep Learning :slight_smile:

2 Likes

This will work when webMethods is the client or calling service to application in cloud?

Hi LL, To be honest, i have never tried this scenario but would love to know your thoughts on the same if you consider trying a POC on it. Thanks!

1 Like

Thank you @ukumar029
your steps here are only for internal/external application inbound to webMethods?

Steps mentioned here are only for POC purpose, and can be customized as per your business requirements.

Hi Udish,
This tutorial is very helpful and clear, but here I am getting the exception as below,
{ “error” : “invalid_request”, “error_description” : “Transport protocol must be HTTPS.” }

Please suggest,

Thanks,
Madhava

@Madhava_Gannu Set this Extended Parameter watt.server.oauth.requireHTTPS to True

2 Likes

Not a best practice to touch server properties like this. Try to resolve it on URI level first if it does not work then resort to the option suggested by you.

1 Like

Hello , can you explain with me which services to get token??
image

Andi,
All these services will generate token. Question is, which grant type you wanted to use? If your use case is, App to App authentication, you must use Client Credential grant type in OAUTH 2.0. If it involves a user authentication, user agent (browser) and app (eg., such as logging to a website using gmail or other creds ), you must use Authorization Code Grant type. So, based on your usecase, choose the appropriate OAUTH 2.0 Grant type, and then use apppriate service in pub.oauth.* services, provide needed parameters as input to retrieve token followed by API call using the token.

Hello, thank you for you shared … i want to ask

how to bypass like that?

i want to auto approve or bypass without approve in one click , thanks …

Hello, Thank you for checking my publication, please refer to point #4 in the Important Points to Ponder section for you to configure auto-approve scenario.

1 Like

Thank you @Senthilkumar_G sir for explaining it in a clear and precise manner, I hope you are doing well. :slight_smile:

Hello, What are the exact steps you followed? Please share. Thanks.

Hi Udish, Now Iam able to access from post man. I have question, for the services you created what are the inputs ? if you can share sample inputs that will be helpful.
especially for grant_types ?

Hi Sandeep, Please refer to admin guide for that. I say this because you will get to know the nuances of each grant type as well :slight_smile:

1 Like

when I try to use Implicit grant type , I get this error

http://XX.XXX.XX.XXX:8888/invoke/pub.oauth/authorize?response_type=token&client_id=e312fff0ec914458b9cc259963e4f249&client_secret=b56e3962321224c97b53720fa672f67fb

Error:
|{ “error” : “unsupported_grant_type”, “error_description” : “[ISS.0010.9020] “grant_type” is invalid. It must be one of “authorization_code”, “refresh_token”, “client_credentials”, “password”.” }|

any thoughts what might is wrong over here ?