Skip to content

Commit

Permalink
add support to verify tokens using public key
Browse files Browse the repository at this point in the history
  • Loading branch information
alan-nettica committed Sep 29, 2024
1 parent f377695 commit bbfcac8
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# go environment
.env

# pem files
*.pem

# Vendor
vendor/*

Expand Down
31 changes: 31 additions & 0 deletions cmd/nettica-api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,37 @@ func main() {
c.Set("oauth2Token", oauth2Token)
c.Next()
return
} else if token != "" {
id_token := c.Request.Header.Get("X-OAUTH2-ID-TOKEN")
if id_token != "" {
new_token := &oauth2.Token{
AccessToken: token,
TokenType: "Bearer",
RefreshToken: "",
Expiry: time.Now().Add(time.Hour * 24),
}
m := make(map[string]interface{})
m["id_token"] = id_token
new_token = new_token.WithExtra(m)

// check if token is valid
oauth2Token, err := util.ValidateToken(new_token.AccessToken)
if err != nil {
log.WithFields(log.Fields{
"err": err,
"token": oauth2Token,
}).Error("failed to get token info")
c.AbortWithStatus(http.StatusUnauthorized)
return
}

// cache token
cacheDb.Set(token, new_token, 4*time.Hour)

// will be accessible in auth endpoints
c.Set("oauth2Token", new_token)
c.Next()
}
}

// avoid 401 page for refresh after logout
Expand Down
49 changes: 49 additions & 0 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import (
"os"
"regexp"
"strings"
"time"

"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt"
"golang.org/x/oauth2"
)

var (
Expand Down Expand Up @@ -259,3 +262,49 @@ func RandomString(n int) (string, error) {

return string(ret), nil
}

// ValidateToken validates a token

func ValidateToken(token string) (*oauth2.Token, error) {
// validate the JWT with our private key

// verify the jwt signature

// parse the token
claims := jwt.MapClaims{}
parsedToken, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) {
bytes, err := os.ReadFile(os.Getenv("OAUTH2_PUBLIC_KEY_PEM"))
if err != nil {
return nil, err
}
return jwt.ParseRSAPublicKeyFromPEM(bytes)
})

if err != nil {
return nil, err
}

// validate the claims
if parsedToken.Valid {

//if claims["email"] == nil || claims["email"] == "" {
// return nil, errors.New("email is required")
//}

// create a new oauth2.Token from the claims
oauth2Token := &oauth2.Token{
AccessToken: token,
TokenType: "Bearer",
RefreshToken: "",
Expiry: time.Now().Add(4 * time.Hour),
}

//oauth2Token = oauth2Token.WithExtra(map[string]interface{}{ // Add the ID token to the extra parameters
// "id_token": token})

return oauth2Token, nil

}

return nil, errors.New("invalid token")
}

0 comments on commit bbfcac8

Please sign in to comment.