HowTo: Develop Secure REST Web Services in GeneXus

Official Content

REST Web Services security is based on Oauth.

Several applications usually expose data update services and data recovery services through REST, so security is very important where privacy of data is a concern.

In GeneXus, the solution to this problem is to use GAM (which hides to the final user the complexity of OAuth technology).

The GAM API provides the way to restrict access to users to REST Web Services defined in the application.

The following is a guide that explains the steps to follow to incorporate security to your REST web services, and the way to consume this web services from a GeneXus application also. The way to consume the web services from a non-GeneXus application should follow the same main idea.

I. From the perspective of the "REST web services" Knowledge Base

1. Create the REST Web Services of your application. The REST web services can be Business Components, Data providers, or procedures, and can expose POST, PUT, DELETE, GET methods.

2. Check the security property in the Knowledge Base (Enable Integrated Security Property). Afterwards, GAM objects will be incorporated to the KB, and a reorganization will be done to create GAM repository, and an initialization of this repository will also be done. For more details see GeneXus Administration of GAM Repository.

3. Create an application using GAM API (or just using the GAM Backend), in order to identify the "REST web services application" within the GAM repository.

4. Create a user which will have access rights to your application. If you want to restrict the access to some users, you need to configure GAM Permissions.

Note that the GAM Examples include a web application (Backend) which facilitates the administration of Applications, GAM Roles, Users, and Permissions.

5. In order to  enable access to the REST services, you need to provide the Client_Id, user, and password to the consumer.

Take a look at "GAMExampleApplicationEntry" object (which belongs to the GAM Examples), to see how to use the GAM API to get the Client_Id.
In particular if you run GAMExampleWWApplications, when you edit  the Application properties of any Application of the Repository, you can see the Client_Id of the Application.

i2016_09_01_13_13_451_png

II. From the perspective of the client application, consumer of "REST web services" Knowledge Base

In Oauth there exists the concept of Client (application), User (userId, userPwd), and permissions (Scope= Read, Write,FullControl..).

A GeneXus application which is configured to use GAM; generates a Client Id for each Application.

To consume a secure GX REST web service you should:

1. Be provided with the Client_Id of the Application, user, and password with access rights to this application.

2. Before trying to POST to the web service, you need first to get an access_token. To get this access_token, you have to POST the Client_Id and user credentials. The detailed steps are as follows:

a. First get the access_token. POST to this URL

HTTP://<SERVER>/<APPDIR>/oauth/access_token

with this body:

client_id=<client_id>&grant_type=password&scope=FullControl&username=<user_name>&password=<user_pwd>

Example body:

client_id=f719771ad52a42919a221bc796d0d6b0&granttype=password&scope=FullControl&username=admin&password=admin123

In the HTTPResponse, there'll be a JSON response with the access_token, as this example shows:

{
  "access token" : "c9919e10e118"   << Access token which will have to be used in all subsequent calls
  "scope" : "FullControl"
}

b. Then all the calls to  the REST web services should include this header (following the same example):
 
Authorization: OAuth c9919e10e118

The following is a complete sample code which shows how to GET de products list ("DPProduct" is a Data Provider exposed as REST web service), which is a secure web service (GAM is enabled in the KB).
The Client Id is taken from the application defined automatically in GAM Backend.

We use HTTPClient data type to consume the REST web service. 

//First get the access_token through an HTTP POST

&addstring ='client_id=be47d883307446b4b93fea47f9264f88&grant_type=password&scope=FullControl&username=test&password=test'

&httpclient.Host= &server
&httpclient.Port = &port

&httpclient.BaseUrl = &urlbase + '/oauth/'  
&httpclient.AddHeader("Content-Type", "application/x-www-form-urlencoded")
&httpclient.AddString(&addstring)
&httpclient.Execute('POST','access_token')

&httpstatus = &httpclient.StatusCode
msg('Http status: ' + &httpstatus,status)
&result = &httpclient.ToString()

&AccessTokenSDT.FromJson(&result) // Load the AccessToken in a SDT which has this structure (*)

//call DPProduct web service

&httpclient.BaseUrl = &urlbase + '/rest/'
&httpclient.AddHeader("Content-Type", "application/json")
&httpclient.AddHeader('Authorization','OAuth ' + &AccessTokenSDT.access_token)
&httpclient.AddHeader("GENEXUS-AGENT","SmartDevice Application")
&httpclient.Execute('GET','DPProduct')

Notes: 

The Genexus-Agent:"SmartDevice Application" header  is mandatory since Xev2u4.

The grant_type in the json body sent to the "access_token" service maps to the GAM Authentication Types, so "password" means Local Authentication and the other possible values are facebook, twitter, google, externalwebservice, custom and device (for Auto Registration).

In case that you get "Error39: application not found", consider adding the following header: Content-Type: application/x-www-form-urlencoded 
 

acesstokensdt

Note that the user information can be obtained after the successful authentication, using the GAMUser static methods.

It's recommended to use HTTPS so the communication channel between client and server is secure.

See Also

Secure Smart Devices applications architecture

Troubleshooting secure rest services

Was this page helpful?
What Is This?
Your feedback about this content is important. Let us know what you think.