git.iko.soy/typeable/oauth2-proxy
on master help sign in
Merge pull request #2540 from kvanzuijlen/update-go-jwt
6d1ef82Joel Speed
.golangci.yml+1
@@ -33,6 +33,7 @@ issues:
33 - gocritic
33 - gocritic
34 - gosec
34 - gosec
35 - goconst
35 - goconst
36+ - revive
36 - path: _test\.go
37 - path: _test\.go
37 linters:
38 linters:
38 - revive
39 - revive
go.mod+2−2
@@ -14,14 +14,14 @@ require (
14 github.com/fsnotify/fsnotify v1.7.0
14 github.com/fsnotify/fsnotify v1.7.0
15 github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344
15 github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344
16 github.com/go-jose/go-jose/v3 v3.0.1
16 github.com/go-jose/go-jose/v3 v3.0.1
17− github.com/golang-jwt/jwt v3.2.2+incompatible
17+ github.com/golang-jwt/jwt/v5 v5.2.0
18 github.com/google/go-cmp v0.6.0
18 github.com/google/go-cmp v0.6.0
19 github.com/google/uuid v1.6.0
19 github.com/google/uuid v1.6.0
20 github.com/gorilla/mux v1.8.1
20 github.com/gorilla/mux v1.8.1
21 github.com/justinas/alice v1.2.0
21 github.com/justinas/alice v1.2.0
22 github.com/mbland/hmacauth v0.0.0-20170912233209-44256dfd4bfa
22 github.com/mbland/hmacauth v0.0.0-20170912233209-44256dfd4bfa
23 github.com/mitchellh/mapstructure v1.5.0
23 github.com/mitchellh/mapstructure v1.5.0
24− github.com/oauth2-proxy/mockoidc v0.0.0-20240213094324-6186c302dcc8
24+ github.com/oauth2-proxy/mockoidc v0.0.0-20240214162133-caebfff84d25
25 github.com/oauth2-proxy/tools/reference-gen v0.0.0-20210118095127-56ffd7384404
25 github.com/oauth2-proxy/tools/reference-gen v0.0.0-20210118095127-56ffd7384404
26 github.com/ohler55/ojg v1.21.1
26 github.com/ohler55/ojg v1.21.1
27 github.com/onsi/ginkgo v1.16.5
27 github.com/onsi/ginkgo v1.16.5
go.sum+6
@@ -79,6 +79,8 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe
79github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
79github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
80github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
80github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
81github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
81github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
82+github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
83+github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
82github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
84github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
83github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
85github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
84github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
86github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
@@ -157,6 +159,8 @@ github.com/oauth2-proxy/mockoidc v0.0.0-20220308204021-b9169deeb282 h1:TQMyrpijt
157github.com/oauth2-proxy/mockoidc v0.0.0-20220308204021-b9169deeb282/go.mod h1:rW25Kyd08Wdn3UVn0YBsDTSvReu0jqpmJKzxITPSjks=
159github.com/oauth2-proxy/mockoidc v0.0.0-20220308204021-b9169deeb282/go.mod h1:rW25Kyd08Wdn3UVn0YBsDTSvReu0jqpmJKzxITPSjks=
158github.com/oauth2-proxy/mockoidc v0.0.0-20240213094324-6186c302dcc8 h1:DGMYYU5GYoPTxE2ZfBcAD/8j6/QZXi9iX4Vp2ojnGOc=
160github.com/oauth2-proxy/mockoidc v0.0.0-20240213094324-6186c302dcc8 h1:DGMYYU5GYoPTxE2ZfBcAD/8j6/QZXi9iX4Vp2ojnGOc=
159github.com/oauth2-proxy/mockoidc v0.0.0-20240213094324-6186c302dcc8/go.mod h1:oHHSFtBUrYeEgVbIyOGqMP65t2ezJCcxeKhXvGpAcKc=
161github.com/oauth2-proxy/mockoidc v0.0.0-20240213094324-6186c302dcc8/go.mod h1:oHHSFtBUrYeEgVbIyOGqMP65t2ezJCcxeKhXvGpAcKc=
162+github.com/oauth2-proxy/mockoidc v0.0.0-20240214162133-caebfff84d25 h1:9bCMuD3TcnjeqjPT2gSlha4asp8NvgcFRYExCaikCxk=
163+github.com/oauth2-proxy/mockoidc v0.0.0-20240214162133-caebfff84d25/go.mod h1:eDjgYHYDJbPLBLsyZ6qRaugP0mX8vePOhZ5id1fdzJw=
160github.com/oauth2-proxy/tools/reference-gen v0.0.0-20210118095127-56ffd7384404 h1:ZpzR4Ou1nhldBG/vEzauoqyaUlofaUcLkv1C/gBK8ls=
164github.com/oauth2-proxy/tools/reference-gen v0.0.0-20210118095127-56ffd7384404 h1:ZpzR4Ou1nhldBG/vEzauoqyaUlofaUcLkv1C/gBK8ls=
161github.com/oauth2-proxy/tools/reference-gen v0.0.0-20210118095127-56ffd7384404/go.mod h1:YpORG8zs14vNlpXvuHYnnDvWazIRaDk02MaY8lafqdI=
165github.com/oauth2-proxy/tools/reference-gen v0.0.0-20210118095127-56ffd7384404/go.mod h1:YpORG8zs14vNlpXvuHYnnDvWazIRaDk02MaY8lafqdI=
162github.com/ohler55/ojg v1.21.0 h1:niqSS6yl3PQZJrqh7pKs/zinl4HebGe8urXEfpvlpYY=
166github.com/ohler55/ojg v1.21.0 h1:niqSS6yl3PQZJrqh7pKs/zinl4HebGe8urXEfpvlpYY=
@@ -270,6 +274,8 @@ golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
270golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
274golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
271golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
275golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
272golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
276golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
277+golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
278+golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
273golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
279golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
274golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM=
280golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM=
275golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
281golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
oauthproxy.go+1−1
@@ -991,7 +991,7 @@ func (p *OAuthProxy) AuthOnly(rw http.ResponseWriter, req *http.Request) {
991
991
992 // we are authenticated
992 // we are authenticated
993 p.addHeadersForProxying(rw, session)
993 p.addHeadersForProxying(rw, session)
994− p.headersChain.Then(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
994+ p.headersChain.Then(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) {
995 rw.WriteHeader(http.StatusAccepted)
995 rw.WriteHeader(http.StatusAccepted)
996 })).ServeHTTP(rw, req)
996 })).ServeHTTP(rw, req)
997}
997}
pkg/app/pagewriter/error_page.go+1−3
@@ -58,8 +58,6 @@ type ErrorPageOpts struct {
58func (e *errorPageWriter) WriteErrorPage(rw http.ResponseWriter, opts ErrorPageOpts) {
58func (e *errorPageWriter) WriteErrorPage(rw http.ResponseWriter, opts ErrorPageOpts) {
59 rw.WriteHeader(opts.Status)
59 rw.WriteHeader(opts.Status)
60
60
61− // We allow unescaped template.HTML since it is user configured options
62− /* #nosec G203 */
63 data := struct {
61 data := struct {
64 Title string
62 Title string
65 Message string
63 Message string
@@ -76,7 +74,7 @@ func (e *errorPageWriter) WriteErrorPage(rw http.ResponseWriter, opts ErrorPageO
76 StatusCode: opts.Status,
74 StatusCode: opts.Status,
77 Redirect: opts.RedirectURL,
75 Redirect: opts.RedirectURL,
78 RequestID: opts.RequestID,
76 RequestID: opts.RequestID,
79− Footer: template.HTML(e.footer),
77+ Footer: template.HTML(e.footer), // #nosec G203 -- We allow unescaped template.HTML since it is user configured options
80 Version: e.version,
78 Version: e.version,
81 }
79 }
82
80
pkg/app/pagewriter/sign_in_page.go+3−5
@@ -55,8 +55,6 @@ type signInPageWriter struct {
55// WriteSignInPage writes the sign-in page to the given response writer.
55// WriteSignInPage writes the sign-in page to the given response writer.
56// It uses the redirectURL to be able to set the final destination for the user post login.
56// It uses the redirectURL to be able to set the final destination for the user post login.
57func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int) {
57func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int) {
58− // We allow unescaped template.HTML since it is user configured options
59− /* #nosec G203 */
60 t := struct {
58 t := struct {
61 ProviderName string
59 ProviderName string
62 SignInMessage template.HTML
60 SignInMessage template.HTML
@@ -69,14 +67,14 @@ func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Req
69 LogoData template.HTML
67 LogoData template.HTML
70 }{
68 }{
71 ProviderName: s.providerName,
69 ProviderName: s.providerName,
72− SignInMessage: template.HTML(s.signInMessage),
70+ SignInMessage: template.HTML(s.signInMessage), // #nosec G203 -- We allow unescaped template.HTML since it is user configured options
73 StatusCode: statusCode,
71 StatusCode: statusCode,
74 CustomLogin: s.displayLoginForm,
72 CustomLogin: s.displayLoginForm,
75 Redirect: redirectURL,
73 Redirect: redirectURL,
76 Version: s.version,
74 Version: s.version,
77 ProxyPrefix: s.proxyPrefix,
75 ProxyPrefix: s.proxyPrefix,
78− Footer: template.HTML(s.footer),
76+ Footer: template.HTML(s.footer), // #nosec G203 -- We allow unescaped template.HTML since it is user configured options
79− LogoData: template.HTML(s.logoData),
77+ LogoData: template.HTML(s.logoData), // #nosec G203 -- We allow unescaped template.HTML since it is user configured options
80 }
78 }
81
79
82 err := s.template.Execute(rw, t)
80 err := s.template.Execute(rw, t)
pkg/header/injector.go+1−1
@@ -72,7 +72,7 @@ func newSecretInjector(name string, source *options.SecretSource) (valueInjector
72 return nil, fmt.Errorf("error getting secret value: %v", err)
72 return nil, fmt.Errorf("error getting secret value: %v", err)
73 }
73 }
74
74
75− return newInjectorFunc(func(header http.Header, session *sessionsapi.SessionState) {
75+ return newInjectorFunc(func(header http.Header, _ *sessionsapi.SessionState) {
76 header.Add(name, string(value))
76 header.Add(name, string(value))
77 }), nil
77 }), nil
78}
78}
pkg/middleware/jwt_session.go+2−3
@@ -114,9 +114,8 @@ func (j *jwtSessionLoader) getBasicToken(token string) (string, error) {
114
114
115 // check user, user+password, or just password for a token
115 // check user, user+password, or just password for a token
116 if j.jwtRegex.MatchString(user) {
116 if j.jwtRegex.MatchString(user) {
117− // Support blank passwords or magic `x-oauth-basic` passwords - nothing else
117+ if password == "x-oauth-basic" || // #nosec G101 -- Support blank passwords or magic `x-oauth-basic` passwords, nothing else
118− /* #nosec G101 */
119− if password == "" || password == "x-oauth-basic" {
118+ password == "" {
120 return user, nil
119 return user, nil
121 }
120 }
122 } else if j.jwtRegex.MatchString(password) {
121 } else if j.jwtRegex.MatchString(password) {
pkg/middleware/jwt_session_test.go+17−20
@@ -14,7 +14,7 @@ import (
14 "time"
14 "time"
15
15
16 "github.com/coreos/go-oidc/v3/oidc"
16 "github.com/coreos/go-oidc/v3/oidc"
17− "github.com/golang-jwt/jwt"
17+ "github.com/golang-jwt/jwt/v5"
18 middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
18 middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
19 sessionsapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
19 sessionsapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
20 . "github.com/onsi/ginkgo"
20 . "github.com/onsi/ginkgo"
@@ -401,7 +401,7 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=`
401 type idTokenClaims struct {
401 type idTokenClaims struct {
402 Email string `json:"email,omitempty"`
402 Email string `json:"email,omitempty"`
403 Verified *bool `json:"email_verified,omitempty"`
403 Verified *bool `json:"email_verified,omitempty"`
404− jwt.StandardClaims
404+ jwt.RegisteredClaims
405 }
405 }
406
406
407 type tokenToSessionTableInput struct {
407 type tokenToSessionTableInput struct {
@@ -451,13 +451,12 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=`
451 },
451 },
452 Entry("with no email", tokenToSessionTableInput{
452 Entry("with no email", tokenToSessionTableInput{
453 idToken: idTokenClaims{
453 idToken: idTokenClaims{
454− StandardClaims: jwt.StandardClaims{
454+ RegisteredClaims: jwt.RegisteredClaims{
455− Audience: "asdf1234",
455+ Audience: jwt.ClaimStrings{"asdf1234"},
456− ExpiresAt: expiresFuture.Unix(),
456+ ExpiresAt: jwt.NewNumericDate(expiresFuture),
457− Id: "id-some-id",
458− IssuedAt: time.Now().Unix(),
457+ IssuedAt: jwt.NewNumericDate(time.Now()),
459 Issuer: "https://issuer.example.com",
458 Issuer: "https://issuer.example.com",
460− NotBefore: 0,
459+ NotBefore: jwt.NewNumericDate(time.Time{}),
461 Subject: "123456789",
460 Subject: "123456789",
462 },
461 },
463 },
462 },
@@ -468,13 +467,12 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=`
468 }),
467 }),
469 Entry("with a verified email", tokenToSessionTableInput{
468 Entry("with a verified email", tokenToSessionTableInput{
470 idToken: idTokenClaims{
469 idToken: idTokenClaims{
471− StandardClaims: jwt.StandardClaims{
470+ RegisteredClaims: jwt.RegisteredClaims{
472− Audience: "asdf1234",
471+ Audience: jwt.ClaimStrings{"asdf1234"},
473− ExpiresAt: expiresFuture.Unix(),
472+ ExpiresAt: jwt.NewNumericDate(expiresFuture),
474− Id: "id-some-id",
475− IssuedAt: time.Now().Unix(),
473+ IssuedAt: jwt.NewNumericDate(time.Now()),
476 Issuer: "https://issuer.example.com",
474 Issuer: "https://issuer.example.com",
477− NotBefore: 0,
475+ NotBefore: jwt.NewNumericDate(time.Time{}),
478 Subject: "123456789",
476 Subject: "123456789",
479 },
477 },
480 Email: "foo@example.com",
478 Email: "foo@example.com",
@@ -487,13 +485,12 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=`
487 }),
485 }),
488 Entry("with a non-verified email", tokenToSessionTableInput{
486 Entry("with a non-verified email", tokenToSessionTableInput{
489 idToken: idTokenClaims{
487 idToken: idTokenClaims{
490− StandardClaims: jwt.StandardClaims{
488+ RegisteredClaims: jwt.RegisteredClaims{
491− Audience: "asdf1234",
489+ Audience: jwt.ClaimStrings{"asdf1234"},
492− ExpiresAt: expiresFuture.Unix(),
490+ ExpiresAt: jwt.NewNumericDate(expiresFuture),
493− Id: "id-some-id",
494− IssuedAt: time.Now().Unix(),
491+ IssuedAt: jwt.NewNumericDate(time.Now()),
495 Issuer: "https://issuer.example.com",
492 Issuer: "https://issuer.example.com",
496− NotBefore: 0,
493+ NotBefore: jwt.NewNumericDate(time.Time{}),
497 Subject: "123456789",
494 Subject: "123456789",
498 },
495 },
499 Email: "foo@example.com",
496 Email: "foo@example.com",
pkg/providers/oidc/provider_verifier_test.go+14−14
@@ -4,7 +4,7 @@ import (
4 "context"
4 "context"
5 "time"
5 "time"
6
6
7− "github.com/golang-jwt/jwt"
7+ "github.com/golang-jwt/jwt/v5"
8 "github.com/oauth2-proxy/mockoidc"
8 "github.com/oauth2-proxy/mockoidc"
9 . "github.com/onsi/ginkgo"
9 . "github.com/onsi/ginkgo"
10 . "github.com/onsi/ginkgo/extensions/table"
10 . "github.com/onsi/ginkgo/extensions/table"
@@ -90,7 +90,7 @@ var _ = Describe("ProviderVerifier", func() {
90
90
91 type verifierTableInput struct {
91 type verifierTableInput struct {
92 modifyOpts func(*ProviderVerifierOptions)
92 modifyOpts func(*ProviderVerifierOptions)
93− modifyClaims func(*jwt.StandardClaims)
93+ modifyClaims func(claims *jwt.RegisteredClaims)
94 expectedError string
94 expectedError string
95 }
95 }
96
96
@@ -109,11 +109,11 @@ var _ = Describe("ProviderVerifier", func() {
109 Expect(err).ToNot(HaveOccurred())
109 Expect(err).ToNot(HaveOccurred())
110
110
111 now := time.Now()
111 now := time.Now()
112− claims := jwt.StandardClaims{
112+ claims := jwt.RegisteredClaims{
113− Audience: m.Config().ClientID,
113+ Audience: jwt.ClaimStrings{m.Config().ClientID},
114 Issuer: m.Issuer(),
114 Issuer: m.Issuer(),
115− ExpiresAt: now.Add(1 * time.Hour).Unix(),
115+ ExpiresAt: jwt.NewNumericDate(now.Add(1 * time.Hour)),
116− IssuedAt: now.Unix(),
116+ IssuedAt: jwt.NewNumericDate(now),
117 Subject: "user",
117 Subject: "user",
118 }
118 }
119 if in.modifyClaims != nil {
119 if in.modifyClaims != nil {
@@ -136,8 +136,8 @@ var _ = Describe("ProviderVerifier", func() {
136 },
136 },
137 Entry("with the default opts and claims", &verifierTableInput{}),
137 Entry("with the default opts and claims", &verifierTableInput{}),
138 Entry("when the audience is mismatched", &verifierTableInput{
138 Entry("when the audience is mismatched", &verifierTableInput{
139− modifyClaims: func(j *jwt.StandardClaims) {
139+ modifyClaims: func(j *jwt.RegisteredClaims) {
140− j.Audience = "OtherClient"
140+ j.Audience = jwt.ClaimStrings{"OtherClient"}
141 },
141 },
142 expectedError: "audience from claim aud with value [OtherClient] does not match with any of allowed audiences",
142 expectedError: "audience from claim aud with value [OtherClient] does not match with any of allowed audiences",
143 }),
143 }),
@@ -145,12 +145,12 @@ var _ = Describe("ProviderVerifier", func() {
145 modifyOpts: func(p *ProviderVerifierOptions) {
145 modifyOpts: func(p *ProviderVerifierOptions) {
146 p.ExtraAudiences = []string{"ExtraIssuer"}
146 p.ExtraAudiences = []string{"ExtraIssuer"}
147 },
147 },
148− modifyClaims: func(j *jwt.StandardClaims) {
148+ modifyClaims: func(j *jwt.RegisteredClaims) {
149− j.Audience = "ExtraIssuer"
149+ j.Audience = jwt.ClaimStrings{"ExtraIssuer"}
150 },
150 },
151 }),
151 }),
152 Entry("when the issuer is mismatched", &verifierTableInput{
152 Entry("when the issuer is mismatched", &verifierTableInput{
153− modifyClaims: func(j *jwt.StandardClaims) {
153+ modifyClaims: func(j *jwt.RegisteredClaims) {
154 j.Issuer = "OtherIssuer"
154 j.Issuer = "OtherIssuer"
155 },
155 },
156 expectedError: "failed to verify token: oidc: id token issued by a different provider",
156 expectedError: "failed to verify token: oidc: id token issued by a different provider",
@@ -159,13 +159,13 @@ var _ = Describe("ProviderVerifier", func() {
159 modifyOpts: func(p *ProviderVerifierOptions) {
159 modifyOpts: func(p *ProviderVerifierOptions) {
160 p.SkipIssuerVerification = true
160 p.SkipIssuerVerification = true
161 },
161 },
162− modifyClaims: func(j *jwt.StandardClaims) {
162+ modifyClaims: func(j *jwt.RegisteredClaims) {
163 j.Issuer = "OtherIssuer"
163 j.Issuer = "OtherIssuer"
164 },
164 },
165 }),
165 }),
166 Entry("when the token has expired", &verifierTableInput{
166 Entry("when the token has expired", &verifierTableInput{
167− modifyClaims: func(j *jwt.StandardClaims) {
167+ modifyClaims: func(j *jwt.RegisteredClaims) {
168− j.ExpiresAt = time.Now().Add(-1 * time.Hour).Unix()
168+ j.ExpiresAt = jwt.NewNumericDate(time.Now().Add(-1 * time.Hour))
169 },
169 },
170 expectedError: "failed to verify token: oidc: token is expired",
170 expectedError: "failed to verify token: oidc: token is expired",
171 }),
171 }),
pkg/upstream/proxy.go+1−1
@@ -122,7 +122,7 @@ func (m *multiUpstreamProxy) registerRewriteHandler(upstream options.Upstream, h
122
122
123 rewrite := newRewritePath(rewriteRegExp, upstream.RewriteTarget, writer)
123 rewrite := newRewritePath(rewriteRegExp, upstream.RewriteTarget, writer)
124 h := alice.New(rewrite).Then(handler)
124 h := alice.New(rewrite).Then(handler)
125− m.serveMux.MatcherFunc(func(req *http.Request, match *mux.RouteMatch) bool {
125+ m.serveMux.MatcherFunc(func(req *http.Request, _ *mux.RouteMatch) bool {
126 return rewriteRegExp.MatchString(req.URL.Path)
126 return rewriteRegExp.MatchString(req.URL.Path)
127 }).Handler(h)
127 }).Handler(h)
128
128
pkg/validation/options.go+1−3
@@ -30,10 +30,8 @@ func Validate(o *options.Options) error {
30 msgs = parseSignatureKey(o, msgs)
30 msgs = parseSignatureKey(o, msgs)
31
31
32 if o.SSLInsecureSkipVerify {
32 if o.SSLInsecureSkipVerify {
33− // InsecureSkipVerify is a configurable option we allow
34− /* #nosec G402 */
35 insecureTransport := &http.Transport{
33 insecureTransport := &http.Transport{
36− TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
34+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // #nosec G402 -- InsecureSkipVerify is a configurable option we allow
37 }
35 }
38 http.DefaultClient = &http.Client{Transport: insecureTransport}
36 http.DefaultClient = &http.Client{Transport: insecureTransport}
39 } else if len(o.Providers[0].CAFiles) > 0 {
37 } else if len(o.Providers[0].CAFiles) > 0 {
providers/adfs_test.go+1−1
@@ -12,7 +12,7 @@ import (
12 "strings"
12 "strings"
13
13
14 "github.com/coreos/go-oidc/v3/oidc"
14 "github.com/coreos/go-oidc/v3/oidc"
15− "github.com/golang-jwt/jwt"
15+ "github.com/golang-jwt/jwt/v5"
16 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
16 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
17 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
17 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
18 internaloidc "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/providers/oidc"
18 internaloidc "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/providers/oidc"
providers/azure_test.go+9−9
@@ -14,7 +14,7 @@ import (
14 "time"
14 "time"
15
15
16 "github.com/coreos/go-oidc/v3/oidc"
16 "github.com/coreos/go-oidc/v3/oidc"
17− "github.com/golang-jwt/jwt"
17+ "github.com/golang-jwt/jwt/v5"
18 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
18 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
19 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
19 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
20 internaloidc "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/providers/oidc"
20 internaloidc "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/providers/oidc"
@@ -311,9 +311,9 @@ func TestAzureProviderRedeem(t *testing.T) {
311 if testCase.EmailFromIDToken != "" {
311 if testCase.EmailFromIDToken != "" {
312 var err error
312 var err error
313 token := idTokenClaims{
313 token := idTokenClaims{
314− StandardClaims: jwt.StandardClaims{Audience: "cd6d4fae-f6a6-4a34-8454-2c6b598e9532"},
314+ RegisteredClaims: jwt.RegisteredClaims{Audience: jwt.ClaimStrings{"cd6d4fae-f6a6-4a34-8454-2c6b598e9532"}},
315− Email: testCase.EmailFromIDToken,
315+ Email: testCase.EmailFromIDToken,
316− Groups: []string{"aa", "bb"},
316+ Groups: []string{"aa", "bb"},
317 }
317 }
318 idTokenString, err = newSignedTestIDToken(token)
318 idTokenString, err = newSignedTestIDToken(token)
319 assert.NoError(t, err)
319 assert.NoError(t, err)
@@ -321,9 +321,9 @@ func TestAzureProviderRedeem(t *testing.T) {
321 if testCase.EmailFromAccessToken != "" {
321 if testCase.EmailFromAccessToken != "" {
322 var err error
322 var err error
323 token := idTokenClaims{
323 token := idTokenClaims{
324− StandardClaims: jwt.StandardClaims{Audience: "cd6d4fae-f6a6-4a34-8454-2c6b598e9532"},
324+ RegisteredClaims: jwt.RegisteredClaims{Audience: jwt.ClaimStrings{"cd6d4fae-f6a6-4a34-8454-2c6b598e9532"}},
325− Email: testCase.EmailFromAccessToken,
325+ Email: testCase.EmailFromAccessToken,
326− Groups: []string{"aa", "bb"},
326+ Groups: []string{"aa", "bb"},
327 }
327 }
328 accessTokenString, err = newSignedTestIDToken(token)
328 accessTokenString, err = newSignedTestIDToken(token)
329 assert.NoError(t, err)
329 assert.NoError(t, err)
@@ -390,8 +390,8 @@ func TestAzureProviderRefresh(t *testing.T) {
390 subject := "foo"
390 subject := "foo"
391 idToken := idTokenClaims{
391 idToken := idTokenClaims{
392 Email: email,
392 Email: email,
393− StandardClaims: jwt.StandardClaims{
393+ RegisteredClaims: jwt.RegisteredClaims{
394− Audience: "cd6d4fae-f6a6-4a34-8454-2c6b598e9532",
394+ Audience: jwt.ClaimStrings{"cd6d4fae-f6a6-4a34-8454-2c6b598e9532"},
395 Subject: subject,
395 Subject: subject,
396 },
396 },
397 }
397 }
providers/logingov.go+6−7
@@ -13,7 +13,7 @@ import (
13 "time"
13 "time"
14
14
15 "github.com/go-jose/go-jose/v3"
15 "github.com/go-jose/go-jose/v3"
16− "github.com/golang-jwt/jwt"
16+ "github.com/golang-jwt/jwt/v5"
17 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
17 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
18 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
18 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
19 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests"
19 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests"
@@ -146,12 +146,12 @@ type loginGovCustomClaims struct {
146 Birthdate string `json:"birthdate"`
146 Birthdate string `json:"birthdate"`
147 AtHash string `json:"at_hash"`
147 AtHash string `json:"at_hash"`
148 CHash string `json:"c_hash"`
148 CHash string `json:"c_hash"`
149− jwt.StandardClaims
149+ jwt.RegisteredClaims
150}
150}
151
151
152// checkNonce checks the nonce in the id_token
152// checkNonce checks the nonce in the id_token
153func checkNonce(idToken string, p *LoginGovProvider) (err error) {
153func checkNonce(idToken string, p *LoginGovProvider) (err error) {
154− token, err := jwt.ParseWithClaims(idToken, &loginGovCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
154+ token, err := jwt.ParseWithClaims(idToken, &loginGovCustomClaims{}, func(_ *jwt.Token) (interface{}, error) {
155 var pubkeys jose.JSONWebKeySet
155 var pubkeys jose.JSONWebKeySet
156 rerr := requests.New(p.PubJWKURL.String()).Do().UnmarshalInto(&pubkeys)
156 rerr := requests.New(p.PubJWKURL.String()).Do().UnmarshalInto(&pubkeys)
157 if rerr != nil {
157 if rerr != nil {
@@ -207,12 +207,11 @@ func (p *LoginGovProvider) Redeem(ctx context.Context, _, code, codeVerifier str
207 return nil, ErrMissingCode
207 return nil, ErrMissingCode
208 }
208 }
209
209
210− claims := &jwt.StandardClaims{
210+ claims := &jwt.RegisteredClaims{
211 Issuer: p.ClientID,
211 Issuer: p.ClientID,
212 Subject: p.ClientID,
212 Subject: p.ClientID,
213− Audience: p.RedeemURL.String(),
213+ Audience: jwt.ClaimStrings{p.RedeemURL.String()},
214− ExpiresAt: time.Now().Add(5 * time.Minute).Unix(),
214+ ExpiresAt: jwt.NewNumericDate(time.Now().Add(5 * time.Minute)),
215− Id: randSeq(32),
216 }
215 }
217 token := jwt.NewWithClaims(jwt.GetSigningMethod("RS256"), claims)
216 token := jwt.NewWithClaims(jwt.GetSigningMethod("RS256"), claims)
218 ss, err := token.SignedString(p.JWTKey)
217 ss, err := token.SignedString(p.JWTKey)
providers/logingov_test.go+13−15
@@ -16,7 +16,7 @@ import (
16 "time"
16 "time"
17
17
18 "github.com/go-jose/go-jose/v3"
18 "github.com/go-jose/go-jose/v3"
19− "github.com/golang-jwt/jwt"
19+ "github.com/golang-jwt/jwt/v5"
20 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
20 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
21 . "github.com/onsi/gomega"
21 . "github.com/onsi/gomega"
22 "github.com/stretchr/testify/assert"
22 "github.com/stretchr/testify/assert"
@@ -174,7 +174,7 @@ func TestLoginGovProviderSessionData(t *testing.T) {
174 Birthdate string `json:"birthdate"`
174 Birthdate string `json:"birthdate"`
175 AtHash string `json:"at_hash"`
175 AtHash string `json:"at_hash"`
176 CHash string `json:"c_hash"`
176 CHash string `json:"c_hash"`
177− jwt.StandardClaims
177+ jwt.RegisteredClaims
178 }
178 }
179 claims := MyCustomClaims{
179 claims := MyCustomClaims{
180 "http://idmanagement.gov/ns/assurance/loa/1",
180 "http://idmanagement.gov/ns/assurance/loa/1",
@@ -186,13 +186,12 @@ func TestLoginGovProviderSessionData(t *testing.T) {
186 "",
186 "",
187 "",
187 "",
188 "",
188 "",
189− jwt.StandardClaims{
189+ jwt.RegisteredClaims{
190− Audience: "Audience",
190+ Audience: jwt.ClaimStrings{"Audience"},
191− ExpiresAt: time.Now().Unix() + expiresIn,
191+ ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(expiresIn) * time.Second)),
192− Id: "foo",
193− IssuedAt: time.Now().Unix(),
192+ IssuedAt: jwt.NewNumericDate(time.Now()),
194 Issuer: "https://idp.int.login.gov",
193 Issuer: "https://idp.int.login.gov",
195− NotBefore: time.Now().Unix() - 1,
194+ NotBefore: jwt.NewNumericDate(time.Now().Add(-1 * time.Second)),
196 Subject: "b2d2d115-1d7e-4579-b9d6-f8e84f4f56ca",
195 Subject: "b2d2d115-1d7e-4579-b9d6-f8e84f4f56ca",
197 },
196 },
198 }
197 }
@@ -268,7 +267,7 @@ func TestLoginGovProviderBadNonce(t *testing.T) {
268 Birthdate string `json:"birthdate"`
267 Birthdate string `json:"birthdate"`
269 AtHash string `json:"at_hash"`
268 AtHash string `json:"at_hash"`
270 CHash string `json:"c_hash"`
269 CHash string `json:"c_hash"`
271− jwt.StandardClaims
270+ jwt.RegisteredClaims
272 }
271 }
273 claims := MyCustomClaims{
272 claims := MyCustomClaims{
274 "http://idmanagement.gov/ns/assurance/loa/1",
273 "http://idmanagement.gov/ns/assurance/loa/1",
@@ -280,13 +279,12 @@ func TestLoginGovProviderBadNonce(t *testing.T) {
280 "",
279 "",
281 "",
280 "",
282 "",
281 "",
283− jwt.StandardClaims{
282+ jwt.RegisteredClaims{
284− Audience: "Audience",
283+ Audience: jwt.ClaimStrings{"Audience"},
285− ExpiresAt: time.Now().Unix() + expiresIn,
284+ ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(expiresIn) * time.Second)),
286− Id: "foo",
287− IssuedAt: time.Now().Unix(),
285+ IssuedAt: jwt.NewNumericDate(time.Now()),
288 Issuer: "https://idp.int.login.gov",
286 Issuer: "https://idp.int.login.gov",
289− NotBefore: time.Now().Unix() - 1,
287+ NotBefore: jwt.NewNumericDate(time.Now().Add(-1 * time.Second)),
290 Subject: "b2d2d115-1d7e-4579-b9d6-f8e84f4f56ca",
288 Subject: "b2d2d115-1d7e-4579-b9d6-f8e84f4f56ca",
291 },
289 },
292 }
290 }
providers/provider_data_test.go+40−48
@@ -19,7 +19,7 @@ import (
19 "github.com/stretchr/testify/assert"
19 "github.com/stretchr/testify/assert"
20
20
21 "github.com/coreos/go-oidc/v3/oidc"
21 "github.com/coreos/go-oidc/v3/oidc"
22− "github.com/golang-jwt/jwt"
22+ "github.com/golang-jwt/jwt/v5"
23 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
23 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
24 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/encryption"
24 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/encryption"
25 internaloidc "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/providers/oidc"
25 internaloidc "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/providers/oidc"
@@ -37,45 +37,44 @@ const (
37 oidcSecret = "SuperSecret123456789"
37 oidcSecret = "SuperSecret123456789"
38 oidcNonce = "abcde12345edcba09876abcde12345ff"
38 oidcNonce = "abcde12345edcba09876abcde12345ff"
39
39
40− failureTokenID = "this-id-fails-verification"
40+ failureIssuer = "this-id-fails-verification"
41)
41)
42
42
43var (
43var (
44 verified = true
44 verified = true
45 unverified = false
45 unverified = false
46
46
47− standardClaims = jwt.StandardClaims{
47+ registeredClaims = jwt.RegisteredClaims{
48− Audience: oidcClientID,
48+ Audience: jwt.ClaimStrings{oidcClientID},
49− ExpiresAt: time.Now().Add(time.Duration(5) * time.Minute).Unix(),
49+ ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(5) * time.Minute)),
50− Id: "id-some-id",
51− IssuedAt: time.Now().Unix(),
50+ IssuedAt: jwt.NewNumericDate(time.Now()),
52 Issuer: oidcIssuer,
51 Issuer: oidcIssuer,
53− NotBefore: 0,
52+ NotBefore: jwt.NewNumericDate(time.Time{}),
54 Subject: "123456789",
53 Subject: "123456789",
55 }
54 }
56
55
57 defaultIDToken = idTokenClaims{
56 defaultIDToken = idTokenClaims{
58− Name: "Jane Dobbs",
57+ Name: "Jane Dobbs",
59− Email: "janed@me.com",
58+ Email: "janed@me.com",
60− Phone: "+4798765432",
59+ Phone: "+4798765432",
61− Picture: "http://mugbook.com/janed/me.jpg",
60+ Picture: "http://mugbook.com/janed/me.jpg",
62− Groups: []string{"test:a", "test:b"},
61+ Groups: []string{"test:a", "test:b"},
63− Roles: []string{"test:c", "test:d"},
62+ Roles: []string{"test:c", "test:d"},
64− Verified: &verified,
63+ Verified: &verified,
65− Nonce: encryption.HashNonce([]byte(oidcNonce)),
64+ Nonce: encryption.HashNonce([]byte(oidcNonce)),
66− StandardClaims: standardClaims,
65+ RegisteredClaims: registeredClaims,
67 }
66 }
68
67
69 numericGroupsIDToken = idTokenClaims{
68 numericGroupsIDToken = idTokenClaims{
70− Name: "Jane Dobbs",
69+ Name: "Jane Dobbs",
71− Email: "janed@me.com",
70+ Email: "janed@me.com",
72− Phone: "+4798765432",
71+ Phone: "+4798765432",
73− Picture: "http://mugbook.com/janed/me.jpg",
72+ Picture: "http://mugbook.com/janed/me.jpg",
74− Groups: []interface{}{1, 2, 3},
73+ Groups: []interface{}{1, 2, 3},
75− Roles: []string{"test:c", "test:d"},
74+ Roles: []string{"test:c", "test:d"},
76− Verified: &verified,
75+ Verified: &verified,
77− Nonce: encryption.HashNonce([]byte(oidcNonce)),
76+ Nonce: encryption.HashNonce([]byte(oidcNonce)),
78− StandardClaims: standardClaims,
77+ RegisteredClaims: registeredClaims,
79 }
78 }
80
79
81 complexGroupsIDToken = idTokenClaims{
80 complexGroupsIDToken = idTokenClaims{
@@ -91,24 +90,24 @@ var (
91 12345,
90 12345,
92 "Just::A::String",
91 "Just::A::String",
93 },
92 },
94− Roles: []string{"test:simple", "test:roles"},
93+ Roles: []string{"test:simple", "test:roles"},
95− Verified: &verified,
94+ Verified: &verified,
96− StandardClaims: standardClaims,
95+ RegisteredClaims: registeredClaims,
97 }
96 }
98
97
99 unverifiedIDToken = idTokenClaims{
98 unverifiedIDToken = idTokenClaims{
100− Name: "Mystery Man",
99+ Name: "Mystery Man",
101− Email: "unverified@email.com",
100+ Email: "unverified@email.com",
102− Phone: "+4025205729",
101+ Phone: "+4025205729",
103− Picture: "http://mugbook.com/unverified/email.jpg",
102+ Picture: "http://mugbook.com/unverified/email.jpg",
104− Groups: []string{"test:a", "test:b"},
103+ Groups: []string{"test:a", "test:b"},
105− Roles: []string{"test:c", "test:d"},
104+ Roles: []string{"test:c", "test:d"},
106− Verified: &unverified,
105+ Verified: &unverified,
107− StandardClaims: standardClaims,
106+ RegisteredClaims: registeredClaims,
108 }
107 }
109
108
110 minimalIDToken = idTokenClaims{
109 minimalIDToken = idTokenClaims{
111− StandardClaims: standardClaims,
110+ RegisteredClaims: registeredClaims,
112 }
111 }
113)
112)
114
113
@@ -121,7 +120,7 @@ type idTokenClaims struct {
121 Roles interface{} `json:"roles,omitempty"`
120 Roles interface{} `json:"roles,omitempty"`
122 Verified *bool `json:"email_verified,omitempty"`
121 Verified *bool `json:"email_verified,omitempty"`
123 Nonce string `json:"nonce,omitempty"`
122 Nonce string `json:"nonce,omitempty"`
124− jwt.StandardClaims
123+ jwt.RegisteredClaims
125}
124}
126
125
127type mockJWKS struct{}
126type mockJWKS struct{}
@@ -134,7 +133,7 @@ func (mockJWKS) VerifySignature(_ context.Context, jwt string) ([]byte, error) {
134
133
135 tokenClaims := &idTokenClaims{}
134 tokenClaims := &idTokenClaims{}
136 err = json.Unmarshal(decoded, tokenClaims)
135 err = json.Unmarshal(decoded, tokenClaims)
137− if err != nil || tokenClaims.Id == failureTokenID {
136+ if err != nil || tokenClaims.Issuer == failureIssuer {
138 return nil, fmt.Errorf("the validation failed for subject [%v]", tokenClaims.Subject)
137 return nil, fmt.Errorf("the validation failed for subject [%v]", tokenClaims.Subject)
139 }
138 }
140
139
@@ -158,7 +157,7 @@ func newTestOauth2Token() *oauth2.Token {
158
157
159func TestProviderData_verifyIDToken(t *testing.T) {
158func TestProviderData_verifyIDToken(t *testing.T) {
160 failureIDToken := defaultIDToken
159 failureIDToken := defaultIDToken
161− failureIDToken.Id = failureTokenID
160+ failureIDToken.Issuer = failureIssuer
162
161
163 testCases := map[string]struct {
162 testCases := map[string]struct {
164 IDToken *idTokenClaims
163 IDToken *idTokenClaims
@@ -172,13 +171,6 @@ func TestProviderData_verifyIDToken(t *testing.T) {
172 ExpectIDToken: true,
171 ExpectIDToken: true,
173 ExpectedError: nil,
172 ExpectedError: nil,
174 },
173 },
175− "Invalid ID Token": {
176− IDToken: &failureIDToken,
177− Verifier: true,
178− ExpectIDToken: false,
179− ExpectedError: errors.New("failed to verify token: failed to verify signature: " +
180− "the validation failed for subject [123456789]"),
181− },
182 "Missing ID Token": {
174 "Missing ID Token": {
183 IDToken: nil,
175 IDToken: nil,
184 Verifier: true,
176 Verifier: true,