Skip to content

Commit

Permalink
feat: accept oidc token as authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
jsiebens committed Feb 4, 2022
1 parent b239cc3 commit 62951e3
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 1 deletion.
8 changes: 8 additions & 0 deletions internal/auth/providers/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ func (p *GitHubProvider) Exchange(redirectURI, code string) (*Identity, error) {
}, nil
}

func (p *GitHubProvider) ExchangeIDToken(rawIdToken string) (*Identity, error) {
return nil, fmt.Errorf("unsupported operation")
}

func (p *GitHubProvider) IsInteractive() bool {
return true
}

func (p *GitHubProvider) getTeams(ctx context.Context, client *github.Client) ([]string, error) {
var result []string
var page = 0
Expand Down
29 changes: 28 additions & 1 deletion internal/auth/providers/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func NewOIDCProvider(c *config.Provider) (*OIDCProvider, error) {
return nil, err
}

verifier := provider.Verifier(&oidc.Config{ClientID: c.ClientID})
verifier := provider.Verifier(&oidc.Config{ClientID: c.ClientID, SkipClientIDCheck: c.ClientID == ""})

return &OIDCProvider{
clientID: c.ClientID,
Expand All @@ -48,6 +48,29 @@ func (p *OIDCProvider) GetLoginURL(redirectURI, state string) string {
return oauth2Config.AuthCodeURL(state)
}

func (p *OIDCProvider) ExchangeIDToken(rawIdToken string) (*Identity, error) {
// Parse and verify ID Token payload.
idToken, err := p.verifier.Verify(context.Background(), rawIdToken)
if err != nil {
return nil, err
}

sub, email, name, tokenClaims, err := p.getTokenClaims(idToken)
if err != nil {
return nil, err
}

return &Identity{
UserID: sub,
Username: name,
Email: email,
Attr: map[string]interface{}{
"provider": "oidc",
"token": tokenClaims,
},
}, nil
}

func (p *OIDCProvider) Exchange(redirectURI, code string) (*Identity, error) {
oauth2Config := oauth2.Config{
ClientID: p.clientID,
Expand Down Expand Up @@ -97,6 +120,10 @@ func (p *OIDCProvider) Exchange(redirectURI, code string) (*Identity, error) {
}, nil
}

func (p *OIDCProvider) IsInteractive() bool {
return p.provider.Endpoint().AuthURL != ""
}

func (p *OIDCProvider) getTokenClaims(idToken *oidc.IDToken) (string, string, string, map[string]interface{}, error) {
var raw = make(map[string]interface{})
var claims struct {
Expand Down
2 changes: 2 additions & 0 deletions internal/auth/providers/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ func NewProvider(c *config.Provider) (AuthProvider, error) {
type AuthProvider interface {
GetLoginURL(redirectURI, state string) string
Exchange(redirectURI, code string) (*Identity, error)
ExchangeIDToken(rawIdToken string) (*Identity, error)
IsInteractive() bool
}

type Identity struct {
Expand Down
39 changes: 39 additions & 0 deletions internal/auth/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,45 @@ func (s *Server) RegisterSession(req *api.RegisterSessionRequest) (*api.SessionT

return &response, nil
}

identity, err := s.provider.ExchangeIDToken(req.AuthToken)
if err == nil {
authorized, roles, err := s.evaluatePolicies(req.Policies, identity)
if err != nil {
return nil, err
}

if !authorized {
return nil, echo.NewHTTPError(http.StatusUnauthorized)
}

st := api.SessionToken{
UserID: identity.UserID,
Username: identity.Username,
Email: identity.Email,
Roles: roles,
Target: req.Target,
ExpirationTime: now.Add(5 * time.Minute).UTC(),
Checksum: req.Checksum,
}

sessionToken, err := s.privateKey.SealBase58(*publicKey, st)
if err != nil {
return nil, err
}

response := api.SessionTokenResponse{
SessionId: req.SessionId,
SessionToken: sessionToken,
AuthToken: req.AuthToken,
}

return &response, nil
}
}

if !s.provider.IsInteractive() {
return nil, echo.NewHTTPError(http.StatusUnauthorized)
}

if err := s.sessions.Set(req.SessionId, &session{PublicKey: *publicKey, Policies: req.Policies, Target: req.Target, Checksum: req.Checksum}); err != nil {
Expand Down

0 comments on commit 62951e3

Please sign in to comment.