105 lines
3.4 KiB
Go
105 lines
3.4 KiB
Go
package rp
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"github.com/caos/oidc/pkg/oidc"
|
|
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
//RelayingParty declares the minimal interface for oidc clients
|
|
type RelayingParty interface {
|
|
|
|
//AuthURL returns the authorization endpoint with a given state
|
|
AuthURL(state string, opts ...AuthURLOpt) string
|
|
|
|
//AuthURLHandler should implement the AuthURL func as http.HandlerFunc
|
|
//(redirecting to the auth endpoint)
|
|
AuthURLHandler(state string) http.HandlerFunc
|
|
|
|
//CodeExchange implements the OIDC Token Request (oauth2 Authorization Code Grant)
|
|
//returning an `Access Token` and `ID Token Claims`
|
|
CodeExchange(ctx context.Context, code string, opts ...CodeExchangeOpt) (*oidc.Tokens, error)
|
|
|
|
//CodeExchangeHandler extends the CodeExchange func,
|
|
//calling the provided callback func on success with additional returned `state`
|
|
CodeExchangeHandler(callback func(http.ResponseWriter, *http.Request, *oidc.Tokens, string)) http.HandlerFunc
|
|
|
|
//ClientCredentials implements the oauth2 Client Credentials Grant
|
|
//requesting an `Access Token` for the client itself, without user context
|
|
ClientCredentials(ctx context.Context, scopes ...string) (*oauth2.Token, error)
|
|
|
|
//Introspects calls the Introspect Endpoint
|
|
//for validating an (access) token
|
|
// Introspect(ctx context.Context, token string) (TokenIntrospectResponse, error)
|
|
|
|
//Userinfo implements the OIDC Userinfo call
|
|
//returning the info of the user for the requested scopes of an access token
|
|
Userinfo()
|
|
}
|
|
|
|
//PasswortGrantRP extends the `RelayingParty` interface with the oauth2 `Password Grant`
|
|
//
|
|
//This interface is separated from the standard `RelayingParty` interface as the `password grant`
|
|
//is part of the oauth2 and therefore OIDC specification, but should only be used when there's no
|
|
//other possibility, so IMHO never ever. Ever.
|
|
type PasswortGrantRP interface {
|
|
RelayingParty
|
|
|
|
//PasswordGrant implements the oauth2 `Password Grant`,
|
|
//requesting an access token with the users `username` and `password`
|
|
PasswordGrant(context.Context, string, string) (*oauth2.Token, error)
|
|
}
|
|
|
|
type Config struct {
|
|
ClientID string
|
|
ClientSecret string
|
|
CallbackURL string
|
|
Issuer string
|
|
Scopes []string
|
|
}
|
|
|
|
type OptionFunc func(RelayingParty)
|
|
|
|
type Endpoints struct {
|
|
oauth2.Endpoint
|
|
IntrospectURL string
|
|
UserinfoURL string
|
|
JKWsURL string
|
|
}
|
|
|
|
func GetEndpoints(discoveryConfig *oidc.DiscoveryConfiguration) Endpoints {
|
|
return Endpoints{
|
|
Endpoint: oauth2.Endpoint{
|
|
AuthURL: discoveryConfig.AuthorizationEndpoint,
|
|
AuthStyle: oauth2.AuthStyleAutoDetect,
|
|
TokenURL: discoveryConfig.TokenEndpoint,
|
|
},
|
|
IntrospectURL: discoveryConfig.IntrospectionEndpoint,
|
|
UserinfoURL: discoveryConfig.UserinfoEndpoint,
|
|
JKWsURL: discoveryConfig.JwksURI,
|
|
}
|
|
}
|
|
|
|
type AuthURLOpt func() []oauth2.AuthCodeOption
|
|
|
|
//WithCodeChallenge sets the `code_challenge` params in the auth request
|
|
func WithCodeChallenge(codeChallenge string) AuthURLOpt {
|
|
return func() []oauth2.AuthCodeOption {
|
|
return []oauth2.AuthCodeOption{
|
|
oauth2.SetAuthURLParam("code_challenge", codeChallenge),
|
|
oauth2.SetAuthURLParam("code_challenge_method", "S256"),
|
|
}
|
|
}
|
|
}
|
|
|
|
type CodeExchangeOpt func() []oauth2.AuthCodeOption
|
|
|
|
//WithCodeVerifier sets the `code_verifier` param in the token request
|
|
func WithCodeVerifier(codeVerifier string) CodeExchangeOpt {
|
|
return func() []oauth2.AuthCodeOption {
|
|
return []oauth2.AuthCodeOption{oauth2.SetAuthURLParam("code_verifier", codeVerifier)}
|
|
}
|
|
}
|