AWS Developer Blog

Building a serverless developer authentication API in Java using AWS Lambda, Amazon DynamoDB, and Amazon Cognito – Part 4

by Jason Fulghum | on | in Java | Permalink | Comments |  Share

In parts 1, 2, and 3 of this series, we used the AWS Toolkit for Eclipse to create a Java Lambda function. This function authenticated a user against an Amazon DynamoDB table (representing a directory of users) and then connected to Amazon Cognito to obtain an OpenID token. This token could then be used to obtain temporary AWS credentials for your mobile app. We tested the function locally in our development environment and used the AWS Toolkit for Eclipse to upload it to AWS Lambda. We will now integrate this Lambda function with Amazon API Gateway so it can be accessed through a RESTful interface from your applications.

First, let’s create a new API. Open the AWS Management Console. From the Application Services drop-down list, choose API Gateway. If this is your first API, choose Get Started. Otherwise, choose the blue Create API button. Type a name for this API (for example, AuthenticationAPI), and then choose the Create API button.

Now that your API has been created, you will see the following page, which shows, as expected, that there are no resources and no methods defined for this API.

We will create methods for our authentication API in a moment, but first, we will create models that define the data exchange for our API. The models are also used by API Gateway to create SDK classes for use in Android, iOS, and JavaScript clients.

To access the navigation menu, choose Resources. From the navigation menu, choose Models. By default, there are two models included with every API: Error and Empty. We will leave these models as they are and create two models that will define objects and attributes for use in our mobile app to send requests and interpret responses to and from our API.

To define the request model, choose the Create button. Set up the model as shown here:

Model Name: AuthenticationRequestModel
Content type: application/json 
Model Schema: 
{ 
  "$schema": "http://json-schema.org/draft-04/schema#", 
  "title": " AuthenticationRequestModel ", 
  "type": "object", 
  "properties": { 
    "userName": { 
      "type": "string" 
    }, 
    "passwordHash": { 
      "type": "string" 
    }
  } 
}

Choose the Create Model button. You may need to scroll down to see it.

Next, create the response model.

Model Name: AuthenticationResponseModel
Content type: application/json
Model Schema: 
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": " AuthenticationResponseModel ",
  "type": "object",
  "properties": 
  {
    "userId": { "type": "integer" },
    "openIdToken": { "type": "string" },
    "status": { "type": "string" }
 }
}

We need to create methods for our API. In true REST fashion, the URI path is composed of resources names. Each resource can have one or many HTTP methods. For our authentication example, we will add one resource, and then attach one method to it. Let’s start by creating a resource called “login.”

From the Models drop-down list, choose Resources.

Choose the Create Resource button. For the name of your resource, type login, and then choose the Create Resource button. This will refresh the dashboard. The new resource will appear in the navigation pane under the root of the URI path.

Choose the Create Method button. In the navigation pane, a drop-down list will appear under the login resource. From the drop-down list, choose POST, and then choose the check icon to confirm. The page will be updated, and the POST action will appear in the navigation pane. On the Setup page for your method, choose the Lambda Function option:

The page will be updated to display Lambda-specific options. From the Lambda Region drop-down list, choose the region (us-east-1) where you created the Lambda function. In the Lambda Function text box, type AuthenticateUser. This field will autocomplete. When a dialog box appears to show the API method has been given permission to invoke the Lambda function, choose OK.

The page shows the flow of the API method.

We will now set the request and response models for the login method. Choose Method Request. The panel will scroll and be updated. In the last row of the panel, choose the triangle next to Request Models. This will display a new panel. Choose Add Model. Choose the AuthenticationRequestModel you created earlier. Make sure you manually add “application/json” as the content type before you apply the changes, and then choose the check icon to confirm.

The procedure to add a model to our method response is slightly different. API Gateway lets you configure responses based on the HTTP response code of the REST invocation. We will restrict ourselves to HTTP 200 (the “OK” response code that signifies successful completion). Choose Method Response. In the response list that appears, choose the triangle next to the 200 response. The list of response models will appear on the right. The Empty model has been applied by default. Because multiple response models can be applied to a method, just as you did with the request model, add the AuthenticationResponseModel to the 200 response. Again, make sure to enter the content type (“application/json”) before you apply the change.

We now have an API resource method tied to a Lambda function that has request and response models defined. Let’s test this setup. In the navigation pane, choose the POST child entry of the /login resource. The flow screen will appear. Choose the Test icon.

Choose the triangle next to Response Body and type a sample JSON body (the same text used to test the Lambda function earlier).

{
   "username":"Dhruv",
   "passwordHash":"8743b52063cd84097a65d1633f5c74f5"
}

Choose the Test button. You may have to scroll down to see it. The function will be executed. The output should be the same as your response model.

The results show the HTTP response headers as well as a log snippet. The flow screen is a powerful tool for fine-tuning your API and testing use cases without having to deploy code.

At this point, you would continue to test your API, and when finished, use the Deploy API button on the Resources page to deploy it to production. Each deployment creates a stage, which is used to track the versions of your API. From the Stage page (accessible from the navigation menu), you can select a stage and then use the Stage Editor page to create a client SDK for your mobile app.

This wraps up our sample implementation of developer authenticated identities. By using the AWS Toolkit for Eclipse, you can do server-side coding and testing in Eclipse, and even deploy your server code, without leaving your IDE. You can test your Lambda code both in the IDE and again after deployment by using the console. In short, we’ve covered a lot of ground in the last four blog posts. We hope we’ve given you plenty of ideas for creating your own serverless applications in AWS. Feel free to share your ideas in the comments below!