forked from dexidp/dex
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request dexidp#179 from bcwaldon/cli-ents
Drive authctl new-client with API
- Loading branch information
Showing
15 changed files
with
441 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"net/http" | ||
|
||
"github.com/coreos-inc/auth/connector" | ||
"github.com/coreos-inc/auth/oidc" | ||
"github.com/coreos-inc/auth/schema" | ||
) | ||
|
||
func newAPIDriver(pcfg oidc.ProviderConfig, creds oidc.ClientCredentials) (driver, error) { | ||
ccfg := oidc.ClientConfig{ | ||
ProviderConfig: pcfg, | ||
Credentials: creds, | ||
} | ||
oc, err := oidc.NewClient(ccfg) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
trans := &oidc.AuthenticatedTransport{ | ||
TokenRefresher: &oidc.ClientCredsTokenRefresher{ | ||
Issuer: pcfg.Issuer, | ||
OIDCClient: oc, | ||
}, | ||
RoundTripper: http.DefaultTransport, | ||
} | ||
hc := &http.Client{Transport: trans} | ||
svc, err := schema.NewWithBasePath(hc, pcfg.Issuer) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &apiDriver{svc: svc}, nil | ||
} | ||
|
||
type apiDriver struct { | ||
svc *schema.Service | ||
} | ||
|
||
func (d *apiDriver) NewClient(meta oidc.ClientMetadata) (*oidc.ClientCredentials, error) { | ||
sc := &schema.Client{ | ||
RedirectURIs: []string{meta.RedirectURL.String()}, | ||
} | ||
|
||
call := d.svc.Clients.Create(sc) | ||
scs, err := call.Do() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
creds := &oidc.ClientCredentials{ | ||
ID: scs.Id, | ||
Secret: scs.Secret, | ||
} | ||
|
||
return creds, nil | ||
} | ||
|
||
func (d *apiDriver) ConnectorConfigs() ([]connector.ConnectorConfig, error) { | ||
return nil, errors.New("unable to get connector configs from HTTP API") | ||
} | ||
|
||
func (d *apiDriver) SetConnectorConfigs(cfgs []connector.ConnectorConfig) error { | ||
return errors.New("unable to set connector configs through HTTP API") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package oidc | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"sync" | ||
|
||
"github.com/coreos-inc/auth/jose" | ||
phttp "github.com/coreos-inc/auth/pkg/http" | ||
) | ||
|
||
type TokenRefresher interface { | ||
// Verify checks if the provided token is currently valid or not. | ||
Verify(jose.JWT) error | ||
|
||
// Refresh attempts to authenticate and retrieve a new token. | ||
Refresh() (jose.JWT, error) | ||
} | ||
|
||
type ClientCredsTokenRefresher struct { | ||
Issuer string | ||
OIDCClient *Client | ||
} | ||
|
||
func (c *ClientCredsTokenRefresher) Verify(jwt jose.JWT) (err error) { | ||
_, err = VerifyClientClaims(jwt, c.Issuer) | ||
return | ||
} | ||
|
||
func (c *ClientCredsTokenRefresher) Refresh() (jwt jose.JWT, err error) { | ||
if err = c.OIDCClient.Healthy(); err != nil { | ||
err = fmt.Errorf("unable to authenticate, unhealthy OIDC client: %v", err) | ||
return | ||
} | ||
|
||
jwt, err = c.OIDCClient.ClientCredsToken([]string{"openid"}) | ||
if err != nil { | ||
err = fmt.Errorf("unable to verify auth code with issuer: %v", err) | ||
return | ||
} | ||
|
||
return | ||
} | ||
|
||
type AuthenticatedTransport struct { | ||
TokenRefresher | ||
http.RoundTripper | ||
|
||
mu sync.Mutex | ||
jwt jose.JWT | ||
} | ||
|
||
func (t *AuthenticatedTransport) verifiedJWT() (jose.JWT, error) { | ||
t.mu.Lock() | ||
defer t.mu.Unlock() | ||
|
||
if t.TokenRefresher.Verify(t.jwt) == nil { | ||
return t.jwt, nil | ||
} | ||
|
||
jwt, err := t.TokenRefresher.Refresh() | ||
if err != nil { | ||
return jose.JWT{}, fmt.Errorf("unable to acquire valid JWT: %v", err) | ||
} | ||
|
||
t.jwt = jwt | ||
return t.jwt, nil | ||
} | ||
|
||
func (t *AuthenticatedTransport) RoundTrip(r *http.Request) (*http.Response, error) { | ||
jwt, err := t.verifiedJWT() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
req := phttp.CopyRequest(r) | ||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", jwt.Encode())) | ||
return t.RoundTripper.RoundTrip(req) | ||
} |
Oops, something went wrong.