https://github.com/nordcloud/cognito-authorizer
Build your AWS API Gateway custom authorizer lambda without the need to handle tokens by yourself. Just implement the logic...
https://github.com/nordcloud/cognito-authorizer
aws-cognito cognito
Last synced: over 1 year ago
JSON representation
Build your AWS API Gateway custom authorizer lambda without the need to handle tokens by yourself. Just implement the logic...
- Host: GitHub
- URL: https://github.com/nordcloud/cognito-authorizer
- Owner: nordcloud
- License: mit
- Created: 2019-07-23T11:06:52.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2022-03-11T13:05:46.000Z (over 4 years ago)
- Last Synced: 2025-03-28T03:24:53.300Z (over 1 year ago)
- Topics: aws-cognito, cognito
- Language: Go
- Size: 37.1 KB
- Stars: 24
- Watchers: 2
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://travis-ci.org/nordcloud/cognito-authorizer) [](https://goreportcard.com/report/github.com/nordcloud/cognito-authorizer)
# Cognito authorizer
A golang packages that abstract out work with JSON web access/identity tokens for AWS API Gateway custom authorizer.
These packages handle:
- access, id and standard tokens
- token verification
- token payload decrypting (claims)
- building proper responses from a custom authorizer
- a M2M token signer helper
You don't need to worry about JWT. The `GetIDClaims`, `GetAccessClaims` and `GetStandardClaims` will do the work for you, so you can focus only on building `APIGatewayCustomAuthorizerPolicy`.
### Docs
- [authorizer](https://godoc.org/github.com/nordcloud/cognito-authorizer/pkg/authorizer#pkg-index)
- [default builder](https://godoc.org/github.com/nordcloud/cognito-authorizer/pkg/authorizer/builder)
- [request signer](https://godoc.org/github.com/nordcloud/cognito-authorizer/pkg/request/auth)
### About resource server context
You can pass a context created by your custom authorizer to the resource server. This is done by satisfying ContextBuilder interface. The method should return a `map[string]interface{}` (this is how AWS golang SDK works) but keys and values in this map have to be *strings*. More info [here](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html).
## Example
Custom authorizer main package
```go
package main
import (
"context"
"fmt"
"os"
"strings"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
log "github.com/sirupsen/logrus"
cognitoAuthorizer "github.com/nordcloud/cognito-authorizer/pkg/authorizer"
)
type PolicyEffect string
const (
allow PolicyEffect = "allow"
deny PolicyEffect = "deny"
)
type Policy struct {
Context *cognitoAuthorizer.Context
}
func (b Policy) BuildPolicy(encodedToken string) (events.APIGatewayCustomAuthorizerPolicy, error) {
accessClaims := &cognitoAuthorizer.AccessTokenClaims{}
err := cognitoAuthorizer.GetAccessClaims(encodedToken, b.Context.DecryptionKeys, accessClaims)
if err != nil {
return events.APIGatewayCustomAuthorizerPolicy{}, err
}
resources := []string{
fmt.Sprintf(
"arn:aws:execute-api:%s:*:%s/%s/*/*",
b.Context.Region,
b.Context.ApplicationID,
b.Context.Stage,
),
}
policy := events.APIGatewayCustomAuthorizerPolicy{
Version: "2012-10-17",
Statement: []events.IAMPolicyStatement{
{
Action: []string{"execute-api:Invoke"},
Effect: string(allow),
Resource: resources,
},
},
}
return policy, nil
}
func (b Policy) BuildContext(encodedToken string) (map[string]interface{}, error) {
accessClaims := &cognitoAuthorizer.AccessTokenClaims{}
err := cognitoAuthorizer.GetAccessClaims(encodedToken, b.Context.DecryptionKeys, accessClaims)
if err != nil {
return map[string]interface{}{}, err
}
context := map[string]interface{}{
"token_scope": accessClaims.Scope,
}
return context, nil
}
var (
sharedContext *cognitoAuthorizer.Context
)
// Init is called on lambda cold start. In this function we pull Cognito keys to verify tokens.
func init() {
sharedContext = &cognitoAuthorizer.Context{
Region: os.Getenv("REGION"),
ApplicationID: os.Getenv("API_APPLICATION_ID"),
Stage: os.Getenv("API_STAGE"),
AllowedUserPoolID: os.Getenv("API_ALLOWED_USER_POOL_ID"),
CognitoClients: strings.Split(os.Getenv("COGNITO_CLIENTS"), ","),
DecryptionKeys: nil,
}
keys, err := cognitoAuthorizer.GetDecryptionKeys(sharedContext.Region, sharedContext.AllowedUserPoolID)
if err != nil {
log.WithField("error", err).Error("Unable to get decryption keys.")
}
sharedContext.DecryptionKeys = keys
log.WithFields(log.Fields{
"region": sharedContext.Region,
"application_id": sharedContext.ApplicationID,
"stage": sharedContext.Stage,
"allowed_user_pool_id": sharedContext.AllowedUserPoolID,
"cognito_clients": sharedContext.CognitoClients,
}).Info("Finished initialization.")
}
func handler(ctx context.Context, event events.APIGatewayCustomAuthorizerRequest) (
events.APIGatewayCustomAuthorizerResponse, error) {
log.WithField("method_arn", event.MethodArn).Info("Authorizer lambda invoked.")
policy := &Policy{
Context: sharedContext,
}
responseBuilder := &cognitoAuthorizer.ResponseBuilder{
Context: sharedContext,
PolicyBuilder: policy,
ContextBuilder: policy,
}
return responseBuilder.BuildResponse(event.AuthorizationToken)
}
func main() {
lambda.Start(handler)
}
```
## Authors
- Grzegorz Bednarski, Nordcloud 🇵🇱
- Kamil Piotrowski, Nordcloud 🇵🇱
- Artur Kowalski, Nordcloud 🇵🇱