@@ -0,0 +1,249 @@
10+ "github.com/coreos/go-oidc/v3/oidc"
11+ . "github.com/onsi/ginkgo"
12+ . "github.com/onsi/gomega"
13+ "gopkg.in/square/go-jose.v2"
16+var _ = Describe("Verify", func() {
17+ ctx := context.Background()
19+ It("Succeeds with default aud behavior", func() {
20+ result, err := verify(ctx, &IDTokenVerificationOptions{
21+ AudienceClaims: []string{"aud"},
23+ ExtraAudiences: []string{},
29+ Expect(err).ToNot(HaveOccurred())
30+ Expect(result.Issuer).To(Equal("https://foo"))
31+ Expect(result.Audience).To(Equal([]string{"1226737"}))
34+ It("Fails with default aud behavior", func() {
35+ result, err := verify(ctx, &IDTokenVerificationOptions{
36+ AudienceClaims: []string{"aud"},
38+ ExtraAudiences: []string{},
43+ Expect(err).To(MatchError("audience from claim aud with value [1226737] does not match with " +
44+ "any of allowed audiences map[7817818:{}]"))
45+ Expect(result).To(BeNil())
48+ It("Succeeds with extra audiences", func() {
49+ result, err := verify(ctx, &IDTokenVerificationOptions{
50+ AudienceClaims: []string{"aud"},
52+ ExtraAudiences: []string{"xyz", "1226737"},
58+ Expect(err).ToNot(HaveOccurred())
59+ Expect(result.Issuer).To(Equal("https://foo"))
60+ Expect(result.Audience).To(Equal([]string{"1226737"}))
63+ It("Fails with extra audiences", func() {
64+ result, err := verify(ctx, &IDTokenVerificationOptions{
65+ AudienceClaims: []string{"aud"},
67+ ExtraAudiences: []string{"xyz", "abc"},
73+ Expect(err).To(MatchError("audience from claim aud with value [1226737] does not match with any " +
74+ "of allowed audiences map[7817818:{} abc:{} xyz:{}]"))
75+ Expect(result).To(BeNil())
78+ It("Succeeds with non default aud behavior", func() {
79+ result, err := verify(ctx, &IDTokenVerificationOptions{
80+ AudienceClaims: []string{"client_id"},
82+ ExtraAudiences: []string{},
88+ Expect(err).ToNot(HaveOccurred())
89+ Expect(result.Issuer).To(Equal("https://foo"))
90+ Expect(result.Audience).To(Equal([]string{"1226737"}))
93+ It("Fails with non default aud behavior", func() {
94+ result, err := verify(ctx, &IDTokenVerificationOptions{
95+ AudienceClaims: []string{"client_id"},
97+ ExtraAudiences: []string{},
100+ ClientID: "1226737",
102+ Expect(err).To(MatchError("audience from claim client_id with value [1226737] does not match with " +
103+ "any of allowed audiences map[7817818:{}]"))
104+ Expect(result).To(BeNil())
107+ It("Succeeds with non default aud behavior and extra audiences", func() {
108+ result, err := verify(ctx, &IDTokenVerificationOptions{
109+ AudienceClaims: []string{"client_id"},
110+ ClientID: "7817818",
111+ ExtraAudiences: []string{"xyz", "1226737"},
114+ ClientID: "1226737",
117+ Expect(err).ToNot(HaveOccurred())
118+ Expect(result.Issuer).To(Equal("https://foo"))
119+ Expect(result.Audience).To(Equal([]string{"1226737"}))
122+ It("Fails with non default aud behavior and extra audiences", func() {
123+ result, err := verify(ctx, &IDTokenVerificationOptions{
124+ AudienceClaims: []string{"client_id"},
125+ ClientID: "7817818",
126+ ExtraAudiences: []string{"xyz", "abc"},
129+ ClientID: "1226737",
132+ Expect(err).To(MatchError("audience from claim client_id with value [1226737] does not match with any " +
133+ "of allowed audiences map[7817818:{} abc:{} xyz:{}]"))
134+ Expect(result).To(BeNil())
137+ It("Fails if audience claim does not exist", func() {
138+ result, err := verify(ctx, &IDTokenVerificationOptions{
139+ AudienceClaims: []string{"not_exists"},
140+ ClientID: "7817818",
141+ ExtraAudiences: []string{"xyz", "abc"},
144+ ClientID: "1226737",
148+ Expect(err).To(MatchError("audience claims [not_exists] do not exist in claims: " +
149+ "map[aud:1226737 client_id:1226737 iss:https://foo]"))
150+ Expect(result).To(BeNil())
153+ It("Succeeds with multiple audiences", func() {
154+ var result, err = verify(ctx, &IDTokenVerificationOptions{
155+ AudienceClaims: []string{"client_id", "aud"},
156+ ClientID: "123456789",
157+ ExtraAudiences: []string{"1226737"},
160+ ClientID: "123456789",
161+ Aud: []string{"1226737", "123456789"},
164+ Expect(err).ToNot(HaveOccurred())
165+ Expect(result.Issuer).To(Equal("https://foo"))
166+ Expect(result.Audience).To(Equal([]string{"123456789"}))
169+ It("Succeeds if aud claim match", func() {
170+ result, err := verify(ctx, &IDTokenVerificationOptions{
171+ AudienceClaims: []string{"client_id", "aud"},
172+ ClientID: "1226737",
173+ ExtraAudiences: []string{"xyz", "abc"},
176+ ClientID: "1226737",
180+ Expect(err).ToNot(HaveOccurred())
181+ Expect(result.Issuer).To(Equal("https://foo"))
182+ Expect(result.Audience).To(Equal([]string{"1226737"}))
186+type payload struct {
187+ Iss string `json:"iss,omitempty"`
188+ Aud interface{} `json:"aud,omitempty"`
189+ ClientID string `json:"client_id,omitempty"`
192+type jwtToken struct {
193+ PrivateKey jose.JSONWebKey
194+ PublicKey jose.JSONWebKey
198+type testVerifier struct {
202+func (t *testVerifier) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {
203+ jws, err := jose.ParseSigned(jwt)
205+ return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
207+ return jws.Verify(&t.jwk)
210+func verify(ctx context.Context, verificationOptions *IDTokenVerificationOptions, payload payload) (*oidc.IDToken, error) {
211+ config := &oidc.Config{
212+ ClientID: "1226737",
213+ SkipClientIDCheck: true,
214+ SkipExpiryCheck: true, // required to not run in expired Token error during testing
216+ rawToken, err := json.Marshal(payload)
220+ token, _ := createToken(rawToken)
221+ verifier := NewVerifier(oidc.NewVerifier("https://foo", &testVerifier{jwk: token.PublicKey}, config), verificationOptions)
222+ return verifier.Verify(ctx, token.Token)
225+func createToken(payload []byte) (*jwtToken, error) {
226+ privateKey, err := rsa.GenerateKey(rand.Reader, 1028)
230+ privateWebKey := jose.JSONWebKey{Key: privateKey, Algorithm: string(jose.RS256), KeyID: ""}
231+ publicWebKey := jose.JSONWebKey{Key: privateKey.Public(), Use: "sig", Algorithm: string(jose.RS256), KeyID: ""}
232+ signer, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.RS256, Key: privateWebKey}, nil)
236+ jws, err := signer.Sign(payload)
240+ data, err := jws.CompactSerialize()
245+ PrivateKey: privateWebKey,
246+ PublicKey: publicWebKey,