Skip to content

Commit

Permalink
feat: additional JWT auth debug information (#681)
Browse files Browse the repository at this point in the history
JWT Claims added to error details field. 

Closes #668
  • Loading branch information
eroznik committed Apr 4, 2021
1 parent 2f6d825 commit d08ab50
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
21 changes: 18 additions & 3 deletions pipeline/authn/authenticator_jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import (
"net/http"

"github.com/form3tech-oss/jwt-go"
"github.com/pkg/errors"

"github.com/ory/go-convenience/jwtx"
"github.com/ory/herodot"
"github.com/pkg/errors"

"github.com/ory/oathkeeper/credentials"
"github.com/ory/oathkeeper/driver/configuration"
Expand Down Expand Up @@ -96,7 +95,7 @@ func (a *AuthenticatorJWT) Authenticate(r *http.Request, session *Authentication
ScopeStrategy: a.c.ToScopeStrategy(cf.ScopeStrategy, "authenticators.jwt.Config.scope_strategy"),
})
if err != nil {
return helper.ErrUnauthorized.WithReason(err.Error()).WithTrace(err)
return a.tryEnrichResultErr(token, helper.ErrUnauthorized.WithReason(err.Error()).WithTrace(err))
}

claims, ok := pt.Claims.(jwt.MapClaims)
Expand All @@ -109,3 +108,19 @@ func (a *AuthenticatorJWT) Authenticate(r *http.Request, session *Authentication

return nil
}

func (a *AuthenticatorJWT) tryEnrichResultErr(token string, err *herodot.DefaultError) *herodot.DefaultError {
t, _ := jwt.ParseWithClaims(token, jwt.MapClaims{}, nil)
if t == nil {
return err
}
claims, ok := t.Claims.(jwt.MapClaims)
if !ok {
return err
}
jsonVal, err2 := json.Marshal(claims)
if err2 != nil {
return err
}
return err.WithDetail("jwt_claims", string(jsonVal))
}
25 changes: 25 additions & 0 deletions pipeline/authn/authenticator_jwt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func TestAuthenticatorJWT(t *testing.T) {
expectExactErr error
expectCode int
expectSess *AuthenticationSession
extraErrAssert func(err error)
}{
{
d: "should fail because no payloads",
Expand Down Expand Up @@ -308,6 +309,27 @@ func TestAuthenticatorJWT(t *testing.T) {
expectErr: true,
expectCode: 401,
},
{
d: "failed JWT authorization results in error with jwt_claims in DetailsField",
r: &http.Request{Header: http.Header{"Authorization": []string{"bearer " + gen(keys[2], jwt.MapClaims{
"sub": "sub",
"exp": now.Add(time.Hour).Unix(),
"scope": []string{"scope-1", "scope-2"},
"realm_access": map[string][]string{
"roles": {
"role-1",
"role-2",
},
},
})}}},
config: `{"required_scope": ["scope-1", "scope-2", "scope-3"]}`,
expectErr: true,
extraErrAssert: func(err error) {
defaultError := err.(*herodot.DefaultError)
require.Error(t, defaultError)
require.Equal(t, fmt.Sprintf("{\"exp\":%v,\"realm_access\":{\"roles\":[\"role-1\",\"role-2\"]},\"scope\":[\"scope-1\",\"scope-2\"],\"sub\":\"sub\"}", now.Add(time.Hour).Unix()), defaultError.DetailsField["jwt_claims"])
},
},
} {
t.Run(fmt.Sprintf("case=%d/description=%s", k, tc.d), func(t *testing.T) {
if tc.setup != nil {
Expand All @@ -325,6 +347,9 @@ func TestAuthenticatorJWT(t *testing.T) {
if tc.expectExactErr != nil {
assert.EqualError(t, err, tc.expectExactErr.Error())
}
if tc.extraErrAssert != nil {
tc.extraErrAssert(err)
}
} else {
require.NoError(t, err, "%#v", errors.Cause(err))
}
Expand Down

0 comments on commit d08ab50

Please sign in to comment.