Application architecture is maturing from traditional monolith to SOA to micro services and now to Serverless Architecture which breaks application into small functions doing specific task, running in server infrastructure which is owned and managed by service provider allowing us to focus on core business logic. In this new cloud computing model, we as application developer are responsible for writing our business logic as functions and submitting it to the cloud provider for its execution in scalable and highly available manner. More about Serverless Architecture can be read on wonderful article here .
In this article, we will see how we can manage access to functions implemented as AWS Lambda and using Oracle Identity Cloud Service and use them in a Single Page Serverless Application. Oracle Identity Cloud Service provides a fully integrated cloud service which deliver all the core identity and access management capabilities including user onboarding and access management, integration with on premise AD/OAM, Identity Federation and Single-Sign-On, Open-ID Connect based authentication, Security using OAuth2, multi-factor authentication and social logins. More about IDCS can be found here.
Single Page Serverless Application Pattern
To emphasize more on the concept and the integration pattern, the use case considered in this blog is kept very simple like a traditional Hello World application. Here is what we will accomplish with the help of this use case:
- We will create 2 Lambda functions - Lambda-Manager and Lambda-Employee.
- These Lambdas will be front-ended by AWS API Gateway.
- A single page Web Application served from AWS S3 will call AWS API Gateway APIs to trigger Lambda to perform specific action implemented.
The following diagram depicts a general Serverless application pattern
Secure Your Lambda
We want to enable role based access to our Lambda functions, so that -
- The function Lambda-Manager is only accessible by users with manager role
- The function Lambda-Employee is only accessible by users with employee role.
Let's see how to do it with Oracle Identity Cloud Service. The general pattern uses Oracle Identity Cloud Service(IDCS) Open-ID Connect Authentication feature to authenticate the user and get the access-token which will be used while calling AWS API Gateway API. AWS API Gateway uses Custom Authorizer to implement the authorization logic which will verify the access-token and call IDCS Rest API to get more information about user to decide if he is allowed to access the Lambda function or not. The following diagram presents and overview of this implementation
Request and Response flow is -
- User access web-page in browser which is served from AWS S3.
- User is redirected to IDCS login page and asked for login credentials.
- User provides username/password, gets authenticated at IDCS and return back with access-token.
- Browser Java-Script makes a call to API with access-token.
- API Gateway using custom authorizer as authorization mechanism calls authorizer function (implemented as another Lambda function) passing access-token.
- Authorizer function validate access-token by verifying signature as first level validation.
- Authorizer function call IDCS Rest API to get more information about the user represented by access-token.
- If the user belong to Group - Manager and requested function is Lambda-Manager(identified by API Gateway API), authorizer create a IAM Allow policy to allow access to Lambda-Manager else create IAM Deny policy and return.
- API Gateway evaluate the return policy, if its Allow Policy calls the Lambda else return with HTTP 403.
Set-up and Configuration
Here are set-up and configuration steps required to implement above flow (Focusing only on security aspects).
- After deploying your Lambda function, define API in AWS API Gateway to call your Lambda function.
- Deploy authorizer Lambda which implements the authorization logic. Authorizer Lambda can implement custom authorization logic as per your application. We will implement this authorization based on user's Group membership in Identity Cloud Service with following validation
- First step is to validate the access token by verifying the signature of the access token. There are various libraries available for JWT, you can use one. You will require signing certificate of your IDCS tenancy which you can acquire using Signing Certificate JWK Rest Endpoint.
- If access-token is valid, you can retrieve the Group Membership using IDCS UserInfo Rest Endpoint.
- Depending on Group Membership, create and return IAM Allow or IAM Deny Policy.
- Create "Custom Authorizer" for your APIs
- Configure the custom authorizer to use the authorizer Lambda created in step #2 with Identity token source as "method.request.header.Authorization". This will allow us to pass access-token in Authorization Header while calling API
- On the IDCS side, create Groups as "SPA-Manager" and "SPA-Employee"
- Create users and assign them to one of the above Groups.
- Create Application in IDCS to define resource for your API Gateway's APIs
- Create a public client in IDCS and add scope for your API resources defined above.
- In the single page app, you validate if the user is already logged in or not by checking for access-token. If access-token is not present, redirect the user to IDCS authorizer URL at
- https://[IDCS Tenant URL]/oauth2/v1/authorize?client_id=[Client-ID]&response_type=token&redirect_uri=[URL where you want to redirect after login]&scope=[API Gateway API URI configured as scope in client] openid groups";
- After successful login, user will be redirected to the "redirect_uri" with the access-token which can be used to call your API. The token is set to the HTTP Authorizer header
This is all you have to do to enable user authentication and access control in your Serverless Application implemented using AWS Lambda using Oracle Identity Cloud Service. You can extend this to enable social login, multi-factor authentication as well as federated login using your on premise enterprise directory.
3. AWS Lambda