Skip to content
This repository was archived by the owner on Jan 24, 2019. It is now read-only.

Commit fd5dcc4

Browse files
committed
Implement refreshing within OIDC provider
1 parent d75f626 commit fd5dcc4

File tree

1 file changed

+53
-15
lines changed

1 file changed

+53
-15
lines changed

providers/oidc.go

+53-15
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,58 @@ func (p *OIDCProvider) Redeem(redirectURL, code string) (s *SessionState, err er
3535
if err != nil {
3636
return nil, fmt.Errorf("token exchange: %v", err)
3737
}
38+
s, err = p.createSessionState(token, ctx)
39+
if err != nil {
40+
return nil, fmt.Errorf("unable to update session: %v", err)
41+
}
42+
return
43+
}
44+
45+
func (p *OIDCProvider) RefreshSessionIfNeeded(s *SessionState) (bool, error) {
46+
if s == nil || s.ExpiresOn.After(time.Now()) || s.RefreshToken == "" {
47+
return false, nil
48+
}
49+
50+
origExpiration := s.ExpiresOn
3851

52+
err := p.redeemRefreshToken(s)
53+
if err != nil {
54+
return false, fmt.Errorf("unable to redeem refresh token: %v", err)
55+
}
56+
57+
fmt.Printf("refreshed id token %s (expired on %s)\n", s, origExpiration)
58+
return true, nil
59+
}
60+
61+
func (p *OIDCProvider) redeemRefreshToken(s *SessionState) (err error) {
62+
c := oauth2.Config{
63+
ClientID: p.ClientID,
64+
ClientSecret: p.ClientSecret,
65+
Endpoint: oauth2.Endpoint{
66+
TokenURL: p.RedeemURL.String(),
67+
},
68+
}
69+
ctx := context.Background()
70+
t := &oauth2.Token{
71+
RefreshToken: s.RefreshToken,
72+
Expiry: time.Now().Add(-time.Hour),
73+
}
74+
token, err := c.TokenSource(ctx, t).Token()
75+
if err != nil {
76+
return fmt.Errorf("failed to get token: %v", err)
77+
}
78+
newSession, err := p.createSessionState(token, ctx)
79+
if err != nil {
80+
return fmt.Errorf("unable to update session: %v", err)
81+
}
82+
s.AccessToken = newSession.AccessToken
83+
s.RefreshToken = newSession.RefreshToken
84+
s.ExpiresOn = newSession.ExpiresOn
85+
s.Email = newSession.Email
86+
return
87+
}
88+
89+
func (p *OIDCProvider) createSessionState(token *oauth2.Token, ctx context.Context) (*SessionState, error) {
3990
rawIDToken, ok := token.Extra("id_token").(string)
4091
if !ok {
4192
return nil, fmt.Errorf("token response did not contain an id_token")
@@ -63,23 +114,10 @@ func (p *OIDCProvider) Redeem(redirectURL, code string) (s *SessionState, err er
63114
return nil, fmt.Errorf("email in id_token (%s) isn't verified", claims.Email)
64115
}
65116

66-
s = &SessionState{
117+
return &SessionState{
67118
AccessToken: token.AccessToken,
68119
RefreshToken: token.RefreshToken,
69120
ExpiresOn: token.Expiry,
70121
Email: claims.Email,
71-
}
72-
73-
return
74-
}
75-
76-
func (p *OIDCProvider) RefreshSessionIfNeeded(s *SessionState) (bool, error) {
77-
if s == nil || s.ExpiresOn.After(time.Now()) || s.RefreshToken == "" {
78-
return false, nil
79-
}
80-
81-
origExpiration := s.ExpiresOn
82-
s.ExpiresOn = time.Now().Add(time.Second).Truncate(time.Second)
83-
fmt.Printf("refreshed access token %s (expired on %s)\n", s, origExpiration)
84-
return false, nil
122+
}, nil
85123
}

0 commit comments

Comments
 (0)