mirror of
https://github.com/int128/kubelogin.git
synced 2026-05-09 01:16:35 +00:00
* Recognize path from redirect url in callback server * Fix lint error and refactor --------- Co-authored-by: Andrew Baxter <> Co-authored-by: Hidetake Iwata <int128@gmail.com>
107 lines
3.3 KiB
Go
107 lines
3.3 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/url"
|
|
|
|
gooidc "github.com/coreos/go-oidc/v3/oidc"
|
|
"github.com/int128/kubelogin/pkg/oidc"
|
|
"github.com/int128/kubelogin/pkg/pkce"
|
|
"github.com/int128/oauth2cli"
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
type AuthCodeURLInput struct {
|
|
State string
|
|
Nonce string
|
|
PKCEParams pkce.Params
|
|
AuthRequestExtraParams map[string]string
|
|
}
|
|
|
|
type ExchangeAuthCodeInput struct {
|
|
Code string
|
|
PKCEParams pkce.Params
|
|
Nonce string
|
|
}
|
|
|
|
type GetTokenByAuthCodeInput struct {
|
|
BindAddress []string
|
|
State string
|
|
Nonce string
|
|
PKCEParams pkce.Params
|
|
AuthRequestExtraParams map[string]string
|
|
LocalServerSuccessHTML string
|
|
LocalServerCertFile string
|
|
LocalServerKeyFile string
|
|
}
|
|
|
|
func (c *client) NegotiatedPKCEMethod() pkce.Method {
|
|
return c.negotiatedPKCEMethod
|
|
}
|
|
|
|
// GetTokenByAuthCode performs the authorization code flow.
|
|
func (c *client) GetTokenByAuthCode(ctx context.Context, in GetTokenByAuthCodeInput, localServerReadyChan chan<- string) (*oidc.TokenSet, error) {
|
|
ctx = c.wrapContext(ctx)
|
|
parsedRedirectURL, err := url.Parse(c.oauth2Config.RedirectURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid redirect url: %w", err)
|
|
}
|
|
config := oauth2cli.Config{
|
|
OAuth2Config: c.oauth2Config,
|
|
State: in.State,
|
|
AuthCodeOptions: authorizationRequestOptions(in.Nonce, in.PKCEParams, in.AuthRequestExtraParams),
|
|
TokenRequestOptions: tokenRequestOptions(in.PKCEParams),
|
|
LocalServerBindAddress: in.BindAddress,
|
|
LocalServerReadyChan: localServerReadyChan,
|
|
LocalServerSuccessHTML: in.LocalServerSuccessHTML,
|
|
LocalServerCallbackPath: parsedRedirectURL.Path,
|
|
LocalServerCertFile: in.LocalServerCertFile,
|
|
LocalServerKeyFile: in.LocalServerKeyFile,
|
|
Logf: c.logger.V(1).Infof,
|
|
}
|
|
token, err := oauth2cli.GetToken(ctx, config)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("oauth2 error: %w", err)
|
|
}
|
|
return c.verifyToken(ctx, token, in.Nonce)
|
|
}
|
|
|
|
// GetAuthCodeURL returns the URL of authentication request for the authorization code flow.
|
|
func (c *client) GetAuthCodeURL(in AuthCodeURLInput) string {
|
|
opts := authorizationRequestOptions(in.Nonce, in.PKCEParams, in.AuthRequestExtraParams)
|
|
return c.oauth2Config.AuthCodeURL(in.State, opts...)
|
|
}
|
|
|
|
// ExchangeAuthCode exchanges the authorization code and token.
|
|
func (c *client) ExchangeAuthCode(ctx context.Context, in ExchangeAuthCodeInput) (*oidc.TokenSet, error) {
|
|
ctx = c.wrapContext(ctx)
|
|
opts := tokenRequestOptions(in.PKCEParams)
|
|
token, err := c.oauth2Config.Exchange(ctx, in.Code, opts...)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("exchange error: %w", err)
|
|
}
|
|
return c.verifyToken(ctx, token, in.Nonce)
|
|
}
|
|
|
|
func authorizationRequestOptions(nonce string, pkceParams pkce.Params, extraParams map[string]string) []oauth2.AuthCodeOption {
|
|
opts := []oauth2.AuthCodeOption{
|
|
oauth2.AccessTypeOffline,
|
|
gooidc.Nonce(nonce),
|
|
}
|
|
if pkceOpt := pkceParams.AuthCodeOption(); pkceOpt != nil {
|
|
opts = append(opts, pkceOpt)
|
|
}
|
|
for key, value := range extraParams {
|
|
opts = append(opts, oauth2.SetAuthURLParam(key, value))
|
|
}
|
|
return opts
|
|
}
|
|
|
|
func tokenRequestOptions(pkceParams pkce.Params) []oauth2.AuthCodeOption {
|
|
if pkceOpt := pkceParams.TokenRequestOption(); pkceOpt != nil {
|
|
return []oauth2.AuthCodeOption{pkceOpt}
|
|
}
|
|
return nil
|
|
}
|