Skip to content

Commit

Permalink
Merge pull request #21 from jeffreylo/jlo/identity-claims
Browse files Browse the repository at this point in the history
Return identities.Claims from ClaimsFrom
  • Loading branch information
cainlevy authored Jun 28, 2022
2 parents 3913e15 + 9dfbbcf commit 2ce5849
Show file tree
Hide file tree
Showing 7 changed files with 276 additions and 27 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## HEAD

## 1.2.0

* Add `authn.ClaimsFrom` and `authn.ClaimsFromWithAudience` to support
extraction of identity token claims.

## 1.1.0

### Added
Expand Down
7 changes: 4 additions & 3 deletions authn/authn.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/http"
"time"

"github.com/keratin/authn-server/app/tokens/identities"
jwt "gopkg.in/square/go-jose.v2/jwt"
)

Expand Down Expand Up @@ -68,13 +69,13 @@ func (ac *Client) SubjectFromWithAudience(idToken string, audience jwt.Audience)
// if and only if the token is a valid JWT that passes all
// verification requirements. If the JWT does not verify, the returned
// error will explain why. This is for debugging purposes.
func (ac *Client) ClaimsFrom(idToken string) (*jwt.Claims, error) {
func (ac *Client) ClaimsFrom(idToken string) (*identities.Claims, error) {
return ac.claimsFromVerifier(idToken, ac.verifier)
}

// ClaimsFromWithAudience works like ClaimsFrom but allows
// specifying a different JWT audience.
func (ac *Client) ClaimsFromWithAudience(idToken string, audience jwt.Audience) (*jwt.Claims, error) {
func (ac *Client) ClaimsFromWithAudience(idToken string, audience jwt.Audience) (*identities.Claims, error) {
verifier, err := newIDTokenVerifierWithAudiences(ac.config.Issuer, audience, ac.kchain)
if err != nil {
return nil, err
Expand All @@ -90,7 +91,7 @@ func (ac *Client) subjectFromVerifier(idToken string, verifier JWTClaimsExtracto
return claims.Subject, nil
}

func (ac *Client) claimsFromVerifier(idToken string, verifier JWTClaimsExtractor) (*jwt.Claims, error) {
func (ac *Client) claimsFromVerifier(idToken string, verifier JWTClaimsExtractor) (*identities.Claims, error) {
claims, err := verifier.GetVerifiedClaims(idToken)
if err != nil {
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions authn/interfaces.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package authn

import (
"github.com/keratin/authn-server/app/tokens/identities"
jose "gopkg.in/square/go-jose.v2"
jwt "gopkg.in/square/go-jose.v2/jwt"
)

// Provides a JSON Web Key from a Key ID
Expand All @@ -14,5 +14,5 @@ type JWKProvider interface {

// Extracts verified in-built claims from a jwt idToken
type JWTClaimsExtractor interface {
GetVerifiedClaims(idToken string) (*jwt.Claims, error)
GetVerifiedClaims(idToken string) (*identities.Claims, error)
}
13 changes: 6 additions & 7 deletions authn/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ import (
"net/url"
"time"

"github.com/keratin/authn-server/app/tokens/identities"
jwt "gopkg.in/square/go-jose.v2/jwt"
)

var (
ErrNoKey = errors.New("No keys found")
)
var ErrNoKey = errors.New("No keys found")

// A JWT Claims extractor (JWTClaimsExtractor) implementation
// which extracts claims from Authn idToken
Expand Down Expand Up @@ -42,7 +41,7 @@ func newIDTokenVerifierWithAudiences(issuer string, audiences jwt.Audience, keyc
}

// Gets verified claims from an Authn idToken
func (verifier *idTokenVerifier) GetVerifiedClaims(idToken string) (*jwt.Claims, error) {
func (verifier *idTokenVerifier) GetVerifiedClaims(idToken string) (*identities.Claims, error) {
var err error

claims, err := verifier.claims(idToken)
Expand All @@ -60,7 +59,7 @@ func (verifier *idTokenVerifier) GetVerifiedClaims(idToken string) (*jwt.Claims,

// Gets claims object from an idToken using the key from keychain
// Key from keychain is fetched using KeyID found in idToken's header
func (verifier *idTokenVerifier) claims(idToken string) (*jwt.Claims, error) {
func (verifier *idTokenVerifier) claims(idToken string) (*identities.Claims, error) {
var err error

idJwt, err := jwt.ParseSigned(idToken)
Expand All @@ -82,7 +81,7 @@ func (verifier *idTokenVerifier) claims(idToken string) (*jwt.Claims, error) {
}
key := keys[0]

claims := &jwt.Claims{}
claims := &identities.Claims{}
err = idJwt.Claims(key, claims)
if err != nil {
return nil, err
Expand All @@ -92,7 +91,7 @@ func (verifier *idTokenVerifier) claims(idToken string) (*jwt.Claims, error) {
}

// Verify the claims against the configured values
func (verifier *idTokenVerifier) verify(claims *jwt.Claims) error {
func (verifier *idTokenVerifier) verify(claims *identities.Claims) error {
var err error

// Validate rest of the claims
Expand Down
16 changes: 10 additions & 6 deletions authn/verifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"testing"
"time"

"github.com/keratin/authn-server/app/tokens/identities"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
jose "gopkg.in/square/go-jose.v2"
Expand All @@ -34,12 +35,15 @@ func TestIDTokenVerifier(t *testing.T) {
// factory defaults
randInt, err := rand.Int(rand.Reader, big.NewInt(99999))
require.NoError(t, err)
defaultClaims := jwt.Claims{
Issuer: issuer,
Audience: jwt.Audience{audience},
Subject: randInt.String(),
Expiry: jwt.NewNumericDate(time.Now().Add(time.Hour)),
IssuedAt: jwt.NewNumericDate(time.Now().Add(-time.Minute)),
defaultClaims := identities.Claims{
AuthTime: jwt.NewNumericDate(time.Now().Add(-time.Hour)),
Claims: jwt.Claims{
Issuer: issuer,
Audience: jwt.Audience{audience},
Subject: randInt.String(),
Expiry: jwt.NewNumericDate(time.Now().Add(time.Hour)),
IssuedAt: jwt.NewNumericDate(time.Now().Add(-time.Minute)),
},
}
defaultSigner, err := jose.NewSigner(
jose.SigningKey{Algorithm: jose.RS256, Key: defaultJWK},
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/keratin/authn-go
go 1.12

require (
github.com/keratin/authn-server v1.15.0
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/stretchr/testify v1.3.0
golang.org/x/crypto v0.0.0-20170619204222-adbae1b6b6fb // indirect
gopkg.in/square/go-jose.v2 v2.1.3
github.com/stretchr/testify v1.5.1
gopkg.in/square/go-jose.v2 v2.3.1
)
Loading

0 comments on commit 2ce5849

Please sign in to comment.