Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dex
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
dex
Commits
b08780e6
Commit
b08780e6
authored
Aug 08, 2016
by
Eric Chiang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*: revendor
parent
dd5c257c
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
237 additions
and
105 deletions
+237
-105
glide.lock
glide.lock
+3
-3
.travis.yml
vendor/github.com/ericchiang/oidc/.travis.yml
+13
-0
README.md
vendor/github.com/ericchiang/oidc/README.md
+11
-4
doc.go
vendor/github.com/ericchiang/oidc/doc.go
+5
-5
app.go
vendor/github.com/ericchiang/oidc/examples/idtoken/app.go
+7
-4
app.go
vendor/github.com/ericchiang/oidc/examples/nonce/app.go
+10
-5
nonce.go
vendor/github.com/ericchiang/oidc/nonce.go
+1
-9
oidc.go
vendor/github.com/ericchiang/oidc/oidc.go
+141
-51
oidc_test.go
vendor/github.com/ericchiang/oidc/oidc_test.go
+43
-21
main.go
vendor/github.com/ericchiang/oidc/oidcproxy/main.go
+3
-3
No files found.
glide.lock
View file @
b08780e6
hash:
4442a097b81856345ae5f80101ad1a692a0b4e5d9b7627f5ad09cd20926122f4
hash:
2af4a276277d2ab2ba9de9b0fd67ab7d6b70c07f4171a9efb225f30306d6f3eb
updated: 2016-08-0
5T09:58:15.61704222
-07:00
updated: 2016-08-0
8T11:20:44.300140564
-07:00
imports:
imports:
- name: github.com/ericchiang/oidc
- name: github.com/ericchiang/oidc
version:
69fec81d167d815f4f455c741b2a94ffaf547ed2
version:
1907f0e61549f9081f26bdf269f11603496c9dee
- name: github.com/golang/protobuf
- name: github.com/golang/protobuf
version: 874264fbbb43f4d91e999fecb4b40143ed611400
version: 874264fbbb43f4d91e999fecb4b40143ed611400
subpackages:
subpackages:
...
...
vendor/github.com/ericchiang/oidc/.travis.yml
0 → 100644
View file @
b08780e6
language
:
go
go
:
-
1.5.4
-
1.6.3
-
tip
notifications
:
email
:
false
matrix
:
allow_failures
:
-
go
:
tip
vendor/github.com/ericchiang/oidc/README.md
View file @
b08780e6
...
@@ -58,6 +58,13 @@ Or the provider can be used to verify and inspect the OpenID Connect
...
@@ -58,6 +58,13 @@ Or the provider can be used to verify and inspect the OpenID Connect
verifier
:=
provider
.
NewVerifier
(
ctx
)
verifier
:=
provider
.
NewVerifier
(
ctx
)
```
```
The verifier itself can be constructed with addition checks, such as verifing a
token was issued for a specific client or hasn't expired.
```
go
verifier
:=
provier
.
NewVerifier
(
ctx
,
oidc
.
VerifyAudience
(
clientID
),
oidc
.
VerifyExpiry
())
```
The returned verifier can be used to ensure the ID Token (a JWT) is signed by the provider.
The returned verifier can be used to ensure the ID Token (a JWT) is signed by the provider.
```
go
```
go
...
@@ -78,19 +85,19 @@ func handleOAuth2Callback(w http.ResponseWriter, r *http.Request) {
...
@@ -78,19 +85,19 @@ func handleOAuth2Callback(w http.ResponseWriter, r *http.Request) {
}
}
// Verify that the ID Token is signed by the provider.
// Verify that the ID Token is signed by the provider.
payload
,
err
:=
verifier
.
Verify
(
rawIDToken
)
idToken
,
err
:=
verifier
.
Verify
(
rawIDToken
)
if
err
!=
nil
{
if
err
!=
nil
{
http
.
Error
(
w
,
"Failed to verify ID Token: "
+
err
.
Error
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
"Failed to verify ID Token: "
+
err
.
Error
(),
http
.
StatusInternalServerError
)
return
return
}
}
// Unmarshal ID Token for expected custom claims.
// Unmarshal ID Token for expected custom claims.
var
idToken
struct
{
var
claims
struct
{
Email
string
`json:"email"`
Email
string
`json:"email"`
EmailVerified
bool
`json:"email_verified"`
EmailVerified
bool
`json:"email_verified"`
}
}
if
err
:=
json
.
Unmarshal
(
payload
,
&
idToken
);
err
!=
nil
{
if
err
:=
idToken
.
Claims
(
&
claims
);
err
!=
nil
{
http
.
Error
(
w
,
"Failed to unmarshal ID Token: "
+
err
.
Error
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
"Failed to unmarshal ID Token
claims
: "
+
err
.
Error
(),
http
.
StatusInternalServerError
)
return
return
}
}
...
...
vendor/github.com/ericchiang/oidc/doc.go
View file @
b08780e6
...
@@ -65,19 +65,19 @@ including verifying the JWT signature. It then returns the payload.
...
@@ -65,19 +65,19 @@ including verifying the JWT signature. It then returns the payload.
}
}
// Verify that the ID Token is signed by the provider.
// Verify that the ID Token is signed by the provider.
payload
, err := verifier.Verify(rawIDToken)
idToken
, err := verifier.Verify(rawIDToken)
if err != nil {
if err != nil {
http.Error(w, "Failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
http.Error(w, "Failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
return
return
}
}
// Unmarshal ID Token for expected custom claims.
// Unmarshal ID Token for expected custom claims.
var
idToken
struct {
var
claims
struct {
Email string `json:"email"`
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
EmailVerified bool `json:"email_verified"`
}
}
if err :=
json.Unmarshal(payload, &idToken
); err != nil {
if err :=
idToken.Claims(&claims
); err != nil {
http.Error(w, "Failed to unmarshal ID Token: "+err.Error(), http.StatusInternalServerError)
http.Error(w, "Failed to unmarshal ID Token
custom claims
: "+err.Error(), http.StatusInternalServerError)
return
return
}
}
...
@@ -123,7 +123,7 @@ The nonce enabled verifier can then be used to verify the nonce while unpacking
...
@@ -123,7 +123,7 @@ The nonce enabled verifier can then be used to verify the nonce while unpacking
}
}
// Verify that the ID Token is signed by the provider and verify the nonce.
// Verify that the ID Token is signed by the provider and verify the nonce.
payload
, err := nonceEnabledVerifier.Verify(rawIDToken)
idToken
, err := nonceEnabledVerifier.Verify(rawIDToken)
if err != nil {
if err != nil {
http.Error(w, "Failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
http.Error(w, "Failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
return
return
...
...
vendor/github.com/ericchiang/oidc/examples/idtoken/app.go
View file @
b08780e6
...
@@ -59,8 +59,7 @@ func main() {
...
@@ -59,8 +59,7 @@ func main() {
http
.
Error
(
w
,
"No id_token field in oauth2 token."
,
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
"No id_token field in oauth2 token."
,
http
.
StatusInternalServerError
)
return
return
}
}
log
.
Println
(
rawIDToken
)
idToken
,
err
:=
verifier
.
Verify
(
rawIDToken
)
idTokenPayload
,
err
:=
verifier
.
Verify
(
rawIDToken
)
if
err
!=
nil
{
if
err
!=
nil
{
http
.
Error
(
w
,
"Failed to verify ID Token: "
+
err
.
Error
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
"Failed to verify ID Token: "
+
err
.
Error
(),
http
.
StatusInternalServerError
)
return
return
...
@@ -68,11 +67,15 @@ func main() {
...
@@ -68,11 +67,15 @@ func main() {
oauth2Token
.
AccessToken
=
"*REDACTED*"
oauth2Token
.
AccessToken
=
"*REDACTED*"
rawMessage
:=
json
.
RawMessage
(
idTokenPayload
)
resp
:=
struct
{
resp
:=
struct
{
OAuth2Token
*
oauth2
.
Token
OAuth2Token
*
oauth2
.
Token
IDTokenClaims
*
json
.
RawMessage
// ID Token payload is just JSON.
IDTokenClaims
*
json
.
RawMessage
// ID Token payload is just JSON.
}{
oauth2Token
,
&
rawMessage
}
}{
oauth2Token
,
new
(
json
.
RawMessage
)}
if
err
:=
idToken
.
Claims
(
&
resp
.
IDTokenClaims
);
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
}
data
,
err
:=
json
.
MarshalIndent
(
resp
,
""
,
" "
)
data
,
err
:=
json
.
MarshalIndent
(
resp
,
""
,
" "
)
if
err
!=
nil
{
if
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
...
...
vendor/github.com/ericchiang/oidc/examples/nonce/app.go
View file @
b08780e6
...
@@ -69,23 +69,28 @@ func main() {
...
@@ -69,23 +69,28 @@ func main() {
http
.
Error
(
w
,
"Failed to exchange token: "
+
err
.
Error
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
"Failed to exchange token: "
+
err
.
Error
(),
http
.
StatusInternalServerError
)
return
return
}
}
rawIDToken
,
ok
:=
oauth2Token
.
Extra
(
"id_token"
)
.
(
string
)
rawIDToken
,
ok
:=
oauth2Token
.
Extra
(
"id_token"
)
.
(
string
)
if
!
ok
{
if
!
ok
{
http
.
Error
(
w
,
"No id_token field in oauth2 token."
,
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
"No id_token field in oauth2 token."
,
http
.
StatusInternalServerError
)
return
return
}
}
// Verify the ID Token signature and nonce.
// Verify the ID Token signature and nonce.
idToken
Payload
,
err
:=
nonceEnabledVerifier
.
Verify
(
rawIDToken
)
idToken
,
err
:=
nonceEnabledVerifier
.
Verify
(
rawIDToken
)
if
err
!=
nil
{
if
err
!=
nil
{
http
.
Error
(
w
,
"Failed to verify ID Token: "
+
err
.
Error
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
"Failed to verify ID Token: "
+
err
.
Error
(),
http
.
StatusInternalServerError
)
return
return
}
}
rawMessage
:=
json
.
RawMessage
(
idTokenPayload
)
resp
:=
struct
{
resp
:=
struct
{
OAuth2Token
*
oauth2
.
Token
OAuth2Token
*
oauth2
.
Token
IDToken
*
json
.
RawMessage
// ID Token payload is just JSON.
IDTokenClaims
*
json
.
RawMessage
// ID Token payload is just JSON.
}{
oauth2Token
,
&
rawMessage
}
}{
oauth2Token
,
new
(
json
.
RawMessage
)}
if
err
:=
idToken
.
Claims
(
&
resp
.
IDTokenClaims
);
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
}
data
,
err
:=
json
.
MarshalIndent
(
resp
,
""
,
" "
)
data
,
err
:=
json
.
MarshalIndent
(
resp
,
""
,
" "
)
if
err
!=
nil
{
if
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
...
...
vendor/github.com/ericchiang/oidc/nonce.go
View file @
b08780e6
package
oidc
package
oidc
import
(
import
(
"encoding/json"
"errors"
"errors"
"fmt"
"golang.org/x/oauth2"
"golang.org/x/oauth2"
)
)
...
@@ -29,13 +27,7 @@ type nonceVerifier struct {
...
@@ -29,13 +27,7 @@ type nonceVerifier struct {
nonceSource
NonceSource
nonceSource
NonceSource
}
}
func
(
n
nonceVerifier
)
verifyIDTokenPayload
(
payload
[]
byte
)
error
{
func
(
n
nonceVerifier
)
verifyIDToken
(
token
*
IDToken
)
error
{
var
token
struct
{
Nonce
string
`json:"nonce"`
}
if
err
:=
json
.
Unmarshal
(
payload
,
&
token
);
err
!=
nil
{
return
fmt
.
Errorf
(
"oidc: failed to unmarshal nonce: %v"
,
err
)
}
if
token
.
Nonce
==
""
{
if
token
.
Nonce
==
""
{
return
errors
.
New
(
"oidc: no nonce present in ID Token"
)
return
errors
.
New
(
"oidc: no nonce present in ID Token"
)
}
}
...
...
vendor/github.com/ericchiang/oidc/oidc.go
View file @
b08780e6
...
@@ -15,9 +15,9 @@ import (
...
@@ -15,9 +15,9 @@ import (
var
(
var
(
// ErrTokenExpired indicates that a token parsed by a verifier has expired.
// ErrTokenExpired indicates that a token parsed by a verifier has expired.
ErrTokenExpired
=
errors
.
New
(
"ID Token expired"
)
ErrTokenExpired
=
errors
.
New
(
"
oidc:
ID Token expired"
)
// ErrNotSupported indicates that the requested optional OpenID Connect endpoint is not supported by the provider.
// ErrNotSupported indicates that the requested optional OpenID Connect endpoint is not supported by the provider.
ErrNotSupported
=
errors
.
New
(
"endpoint not supported"
)
ErrNotSupported
=
errors
.
New
(
"
oidc:
endpoint not supported"
)
)
)
const
(
const
(
...
@@ -44,8 +44,8 @@ type Provider struct {
...
@@ -44,8 +44,8 @@ type Provider struct {
JWKSURL
string
`json:"jwks_uri"`
JWKSURL
string
`json:"jwks_uri"`
UserInfoURL
string
`json:"userinfo_endpoint"`
UserInfoURL
string
`json:"userinfo_endpoint"`
//
Optionally contains extra claims
.
//
Raw claims returned by the server
.
raw
map
[
string
]
interface
{}
raw
Claims
[]
byte
}
}
// NewProvider uses the OpenID Connect disovery mechanism to construct a Provider.
// NewProvider uses the OpenID Connect disovery mechanism to construct a Provider.
...
@@ -67,20 +67,19 @@ func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
...
@@ -67,20 +67,19 @@ func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
if
err
:=
json
.
Unmarshal
(
body
,
&
p
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
body
,
&
p
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"oidc: failed to decode provider discovery object: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"oidc: failed to decode provider discovery object: %v"
,
err
)
}
}
// raw claims do not get error checks
p
.
rawClaims
=
body
json
.
Unmarshal
(
body
,
&
p
.
raw
)
if
p
.
Issuer
!=
issuer
{
if
p
.
Issuer
!=
issuer
{
return
nil
,
fmt
.
Errorf
(
"oidc: issuer did not match the issuer returned by provider, expected %q got %q"
,
issuer
,
p
.
Issuer
)
return
nil
,
fmt
.
Errorf
(
"oidc: issuer did not match the issuer returned by provider, expected %q got %q"
,
issuer
,
p
.
Issuer
)
}
}
return
&
p
,
nil
return
&
p
,
nil
}
}
//
Extra
returns additional fields returned by the server during discovery.
//
Claims
returns additional fields returned by the server during discovery.
func
(
p
*
Provider
)
Extra
(
key
string
)
interface
{}
{
func
(
p
*
Provider
)
Claims
(
v
interface
{})
error
{
if
p
.
raw
!
=
nil
{
if
p
.
raw
Claims
=
=
nil
{
return
p
.
raw
[
key
]
return
errors
.
New
(
"oidc: claims not set"
)
}
}
return
nil
return
json
.
Unmarshal
(
p
.
rawClaims
,
v
)
}
}
// Endpoint returns the OAuth2 auth and token endpoints for the given provider.
// Endpoint returns the OAuth2 auth and token endpoints for the given provider.
...
@@ -95,16 +94,15 @@ type UserInfo struct {
...
@@ -95,16 +94,15 @@ type UserInfo struct {
Email
string
`json:"email"`
Email
string
`json:"email"`
EmailVerified
bool
`json:"email_verified"`
EmailVerified
bool
`json:"email_verified"`
// Optionally contains extra claims.
claims
[]
byte
raw
map
[
string
]
interface
{}
}
}
//
Extra returns additional claims returned by the server
.
//
Claims unmarshals the raw JSON object claims into the provided object
.
func
(
u
*
UserInfo
)
Extra
(
key
string
)
interface
{}
{
func
(
u
*
UserInfo
)
Claims
(
v
interface
{})
error
{
if
u
.
raw
!
=
nil
{
if
u
.
claims
=
=
nil
{
return
u
.
raw
[
key
]
return
errors
.
New
(
"oidc: claims not set"
)
}
}
return
nil
return
json
.
Unmarshal
(
u
.
claims
,
v
)
}
}
// UserInfo uses the token source to query the provider's user info endpoint.
// UserInfo uses the token source to query the provider's user info endpoint.
...
@@ -130,11 +128,101 @@ func (p *Provider) UserInfo(ctx context.Context, tokenSource oauth2.TokenSource)
...
@@ -130,11 +128,101 @@ func (p *Provider) UserInfo(ctx context.Context, tokenSource oauth2.TokenSource)
if
err
:=
json
.
Unmarshal
(
body
,
&
userInfo
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
body
,
&
userInfo
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"oidc: failed to decode userinfo: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"oidc: failed to decode userinfo: %v"
,
err
)
}
}
// raw claims do not get error checks
userInfo
.
claims
=
body
json
.
Unmarshal
(
body
,
&
userInfo
.
raw
)
return
&
userInfo
,
nil
return
&
userInfo
,
nil
}
}
// IDToken is an OpenID Connect extension that provides a predictable representation
// of an authorization event.
//
// The ID Token only holds fields OpenID Connect requires. To access additional
// claims returned by the server, use the Claims method.
//
// idToken, err := idTokenVerifier.Verify(rawIDToken)
// if err != nil {
// // handle error
// }
// var claims struct {
// Email string `json:"email"`
// EmailVerified bool `json:"email_verified"`
// }
// if err := idToken.Claims(&claims); err != nil {
// // handle error
// }
//
type
IDToken
struct
{
// The URL of the server which issued this token. This will always be the same
// as the URL used for initial discovery.
Issuer
string
// The client, or set of clients, that this token is issued for.
Audience
[]
string
// A unique string which identifies the end user.
Subject
string
IssuedAt
time
.
Time
Expiry
time
.
Time
Nonce
string
claims
[]
byte
}
// Claims unmarshals the raw JSON payload of the ID Token into a provided struct.
func
(
i
*
IDToken
)
Claims
(
v
interface
{})
error
{
if
i
.
claims
==
nil
{
return
errors
.
New
(
"oidc: claims not set"
)
}
return
json
.
Unmarshal
(
i
.
claims
,
v
)
}
type
audience
[]
string
func
(
a
*
audience
)
UnmarshalJSON
(
b
[]
byte
)
error
{
var
s
string
if
json
.
Unmarshal
(
b
,
&
s
)
==
nil
{
*
a
=
audience
{
s
}
return
nil
}
var
auds
[]
string
if
err
:=
json
.
Unmarshal
(
b
,
&
auds
);
err
!=
nil
{
return
err
}
*
a
=
audience
(
auds
)
return
nil
}
type
jsonTime
time
.
Time
func
(
j
*
jsonTime
)
UnmarshalJSON
(
b
[]
byte
)
error
{
var
n
json
.
Number
if
err
:=
json
.
Unmarshal
(
b
,
&
n
);
err
!=
nil
{
return
err
}
var
unix
int64
if
t
,
err
:=
n
.
Int64
();
err
==
nil
{
unix
=
t
}
else
{
f
,
err
:=
n
.
Float64
()
if
err
!=
nil
{
return
err
}
unix
=
int64
(
f
)
}
*
j
=
jsonTime
(
time
.
Unix
(
unix
,
0
))
return
nil
}
type
idToken
struct
{
Issuer
string
`json:"iss"`
Subject
string
`json:"sub"`
Audience
audience
`json:"aud"`
Expiry
jsonTime
`json:"exp"`
IssuedAt
jsonTime
`json:"iat"`
Nonce
string
`json:"nonce"`
}
// IDTokenVerifier provides verification for ID Tokens.
// IDTokenVerifier provides verification for ID Tokens.
type
IDTokenVerifier
struct
{
type
IDTokenVerifier
struct
{
issuer
string
issuer
string
...
@@ -143,31 +231,34 @@ type IDTokenVerifier struct {
...
@@ -143,31 +231,34 @@ type IDTokenVerifier struct {
}
}
// Verify parse the raw ID Token, verifies it's been signed by the provider, preforms
// Verify parse the raw ID Token, verifies it's been signed by the provider, preforms
// additional verification,
such as checking the expiration,
and returns the claims.
// additional verification, and returns the claims.
func
(
v
*
IDTokenVerifier
)
Verify
(
rawIDToken
string
)
(
payload
[]
byte
,
err
error
)
{
func
(
v
*
IDTokenVerifier
)
Verify
(
rawIDToken
string
)
(
*
IDToken
,
error
)
{
payload
,
err
=
v
.
keySet
.
verifyJWT
(
rawIDToken
)
payload
,
err
:
=
v
.
keySet
.
verifyJWT
(
rawIDToken
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
var
token
struct
{
var
token
idToken
Exp
float64
`json:"exp"`
// JSON numbers are always float64s.
Issuer
string
`json:"iss"`
}
if
err
:=
json
.
Unmarshal
(
payload
,
&
token
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
payload
,
&
token
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"oidc: failed to unmarshal claims: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"oidc: failed to unmarshal claims: %v"
,
err
)
}
}
if
v
.
issuer
!=
token
.
Issuer
{
if
v
.
issuer
!=
token
.
Issuer
{
return
nil
,
fmt
.
Errorf
(
"oidc: iss field did not match provider issuer"
)
return
nil
,
fmt
.
Errorf
(
"oidc: iss field did not match provider issuer"
)
}
}
if
time
.
Unix
(
int64
(
token
.
Exp
),
0
)
.
Before
(
time
.
Now
()
.
Round
(
time
.
Second
))
{
t
:=
&
IDToken
{
return
nil
,
ErrTokenExpired
Issuer
:
token
.
Issuer
,
Subject
:
token
.
Subject
,
Audience
:
[]
string
(
token
.
Audience
),
Expiry
:
time
.
Time
(
token
.
Expiry
),
IssuedAt
:
time
.
Time
(
token
.
Expiry
),
Nonce
:
token
.
Nonce
,
claims
:
payload
,
}
}
for
_
,
option
:=
range
v
.
options
{
for
_
,
option
:=
range
v
.
options
{
if
err
:=
option
.
verifyIDToken
Payload
(
payload
);
err
!=
nil
{
if
err
:=
option
.
verifyIDToken
(
t
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
}
}
return
payload
,
nil
return
t
,
nil
}
}
// NewVerifier returns an IDTokenVerifier that uses the provider's key set to verify JWTs.
// NewVerifier returns an IDTokenVerifier that uses the provider's key set to verify JWTs.
...
@@ -184,7 +275,7 @@ func (p *Provider) NewVerifier(ctx context.Context, options ...VerificationOptio
...
@@ -184,7 +275,7 @@ func (p *Provider) NewVerifier(ctx context.Context, options ...VerificationOptio
// VerificationOption is an option provided to Provider.NewVerifier.
// VerificationOption is an option provided to Provider.NewVerifier.
type
VerificationOption
interface
{
type
VerificationOption
interface
{
verifyIDToken
Payload
(
raw
[]
byte
)
error
verifyIDToken
(
token
*
IDToken
)
error
}
}
// VerifyAudience ensures that an ID Token was issued for the specific client.
// VerifyAudience ensures that an ID Token was issued for the specific client.
...
@@ -199,25 +290,8 @@ type clientVerifier struct {
...
@@ -199,25 +290,8 @@ type clientVerifier struct {
clientID
string
clientID
string
}
}
func
(
c
clientVerifier
)
verifyIDTokenPayload
(
payload
[]
byte
)
error
{
func
(
c
clientVerifier
)
verifyIDToken
(
token
*
IDToken
)
error
{
var
token
struct
{
for
_
,
aud
:=
range
token
.
Audience
{
Aud
string
`json:"aud"`
}
if
err
:=
json
.
Unmarshal
(
payload
,
&
token
);
err
==
nil
{
if
token
.
Aud
!=
c
.
clientID
{
return
errors
.
New
(
"oidc: id token aud field did not match client_id"
)
}
return
nil
}
// Aud can optionally be an array of strings
var
token2
struct
{
Aud
[]
string
`json:"aud"`
}
if
err
:=
json
.
Unmarshal
(
payload
,
&
token2
);
err
!=
nil
{
return
fmt
.
Errorf
(
"oidc: failed to unmarshal aud claim: %v"
,
err
)
}
for
_
,
aud
:=
range
token2
.
Aud
{
if
aud
==
c
.
clientID
{
if
aud
==
c
.
clientID
{
return
nil
return
nil
}
}
...
@@ -225,6 +299,22 @@ func (c clientVerifier) verifyIDTokenPayload(payload []byte) error {
...
@@ -225,6 +299,22 @@ func (c clientVerifier) verifyIDTokenPayload(payload []byte) error {
return
errors
.
New
(
"oidc: id token aud field did not match client_id"
)
return
errors
.
New
(
"oidc: id token aud field did not match client_id"
)
}
}
// VerifyExpiry ensures that an ID Token has not expired.
func
VerifyExpiry
()
VerificationOption
{
return
expiryVerifier
{
time
.
Now
}
}
type
expiryVerifier
struct
{
now
func
()
time
.
Time
}
func
(
e
expiryVerifier
)
verifyIDToken
(
token
*
IDToken
)
error
{
if
e
.
now
()
.
After
(
token
.
Expiry
)
{
return
ErrTokenExpired
}
return
nil
}
// This method is internal to golang.org/x/oauth2. Just copy it.
// This method is internal to golang.org/x/oauth2. Just copy it.
func
contextClient
(
ctx
context
.
Context
)
*
http
.
Client
{
func
contextClient
(
ctx
context
.
Context
)
*
http
.
Client
{
if
ctx
!=
nil
{
if
ctx
!=
nil
{
...
...
vendor/github.com/ericchiang/oidc/oidc_test.go
View file @
b08780e6
package
oidc
package
oidc
import
"testing"
import
(
"encoding/json"
"reflect"
"testing"
)
func
TestClientVerifier
(
t
*
testing
.
T
)
{
func
TestClientVerifier
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
tests
:=
[]
struct
{
clientID
string
clientID
string
payload
string
aud
[]
string
wantErr
bool
wantErr
bool
}{
}{
{
{
clientID
:
"1"
,
clientID
:
"1"
,
payload
:
`{"aud":"1"}`
,
aud
:
[]
string
{
"1"
}
,
},
},
{
{
clientID
:
"1"
,
clientID
:
"1"
,
payload
:
`{"aud":"2"}`
,
aud
:
[]
string
{
"2"
}
,
wantErr
:
true
,
wantErr
:
true
,
},
},
{
{
clientID
:
"1"
,
clientID
:
"1"
,
payload
:
`{"aud":["1"]}`
,
aud
:
[]
string
{
"2"
,
"1"
},
},
{
clientID
:
"1"
,
payload
:
`{"aud":["1", "2"]}`
,
},
{
clientID
:
"3"
,
payload
:
`{"aud":["1", "2"]}`
,
wantErr
:
true
,
},
},
{
{
clientID
:
"3"
,
clientID
:
"3"
,
payload
:
`{"aud":}`
,
// invalid JSON
aud
:
[]
string
{
"1"
,
"2"
},
wantErr
:
true
,
},
{
clientID
:
"1"
,
payload
:
`{}`
,
wantErr
:
true
,
wantErr
:
true
,
},
},
}
}
for
i
,
tc
:=
range
tests
{
for
i
,
tc
:=
range
tests
{
err
:=
(
clientVerifier
{
tc
.
clientID
})
.
verifyIDTokenPayload
([]
byte
(
tc
.
payload
))
token
:=
IDToken
{
Audience
:
tc
.
aud
}
err
:=
(
clientVerifier
{
tc
.
clientID
})
.
verifyIDToken
(
&
token
)
if
err
!=
nil
&&
!
tc
.
wantErr
{
if
err
!=
nil
&&
!
tc
.
wantErr
{
t
.
Errorf
(
"case %d: %v"
,
i
)
t
.
Errorf
(
"case %d: %v"
,
i
)
}
}
...
@@ -52,3 +43,34 @@ func TestClientVerifier(t *testing.T) {
...
@@ -52,3 +43,34 @@ func TestClientVerifier(t *testing.T) {
}
}
}
}
}
}
func
TestUnmarshalAudience
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
data
string
want
audience
wantErr
bool
}{
{
`"foo"`
,
audience
{
"foo"
},
false
},
{
`["foo","bar"]`
,
audience
{
"foo"
,
"bar"
},
false
},
{
"foo"
,
nil
,
true
},
// invalid JSON
}
for
_
,
tc
:=
range
tests
{
var
a
audience
if
err
:=
json
.
Unmarshal
([]
byte
(
tc
.
data
),
&
a
);
err
!=
nil
{
if
!
tc
.
wantErr
{
t
.
Errorf
(
"failed to unmarshal %q: %v"
,
tc
.
data
,
err
)
}
continue
}
if
tc
.
wantErr
{
t
.
Errorf
(
"did not expected to be able to unmarshal %q"
,
tc
.
data
)
continue
}
if
!
reflect
.
DeepEqual
(
tc
.
want
,
a
)
{
t
.
Errorf
(
"from %q expected %q got %q"
,
tc
.
data
,
tc
.
want
,
a
)
}
}
}
vendor/github.com/ericchiang/oidc/oidcproxy/main.go
View file @
b08780e6
...
@@ -3,7 +3,6 @@ package main
...
@@ -3,7 +3,6 @@ package main
import
(
import
(
"crypto/rand"
"crypto/rand"
"encoding/gob"
"encoding/gob"
"encoding/json"
"flag"
"flag"
"fmt"
"fmt"
"io"
"io"
...
@@ -192,7 +191,7 @@ func handleCallback(w http.ResponseWriter, r *http.Request) {
...
@@ -192,7 +191,7 @@ func handleCallback(w http.ResponseWriter, r *http.Request) {
return
httpError
(
http
.
StatusInternalServerError
,
"Authentication failed"
)
return
httpError
(
http
.
StatusInternalServerError
,
"Authentication failed"
)
}
}
payload
,
err
:=
verifier
.
Verify
(
rawIDToken
)
idToken
,
err
:=
verifier
.
Verify
(
rawIDToken
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Printf
(
"Failed to verify token: %v"
,
err
)
log
.
Printf
(
"Failed to verify token: %v"
,
err
)
return
httpError
(
http
.
StatusInternalServerError
,
"Authentication failed"
)
return
httpError
(
http
.
StatusInternalServerError
,
"Authentication failed"
)
...
@@ -201,7 +200,8 @@ func handleCallback(w http.ResponseWriter, r *http.Request) {
...
@@ -201,7 +200,8 @@ func handleCallback(w http.ResponseWriter, r *http.Request) {
Email
string
`json:"email"`
Email
string
`json:"email"`
EmailVerified
bool
`json:"email_verified"`
EmailVerified
bool
`json:"email_verified"`
}
}
if
err
:=
json
.
Unmarshal
(
payload
,
&
claims
);
err
!=
nil
{
if
err
:=
idToken
.
Claims
(
&
claims
);
err
!=
nil
{
log
.
Printf
(
"Failed to decode claims: %v"
,
err
)
log
.
Printf
(
"Failed to decode claims: %v"
,
err
)
return
httpError
(
http
.
StatusInternalServerError
,
"Authentication failed"
)
return
httpError
(
http
.
StatusInternalServerError
,
"Authentication failed"
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment