Skip to content
This repository has been archived by the owner on Oct 9, 2023. It is now read-only.

Commit

Permalink
Expose openId metadata endpoint and expose scopes in /config endpoint
Browse files Browse the repository at this point in the history
Signed-off-by: Haytham Abuelfutuh <[email protected]>
  • Loading branch information
EngHabu committed Feb 27, 2021
1 parent 954416e commit 28ff50d
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 35 deletions.
6 changes: 5 additions & 1 deletion cmd/entrypoints/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,12 @@ func newHTTPServer(ctx context.Context, cfg *config.ServerConfig, authContext in
if authContext.GetUserInfoURL() != nil && authContext.GetUserInfoURL().String() != "" {
mux.HandleFunc("/me", auth.GetMeEndpointHandler(ctx, authContext))
}

// The metadata endpoint is an RFC-defined constant, but we need a leading / for the handler to pattern match correctly.
mux.HandleFunc(fmt.Sprintf("/%s", auth.OIdCMetadataEndpoint), auth.GetOIdCMetadataEndpointRedirectHandler(ctx, authContext))

// The metadata endpoint is an RFC-defined constant, but we need a leading / for the handler to pattern match correctly.
mux.HandleFunc(fmt.Sprintf("/%s", auth.MetadataEndpoint), auth.GetMetadataEndpointRedirectHandler(ctx, authContext))
mux.HandleFunc(fmt.Sprintf("/%s", auth.OAuth2MetadataEndpoint), auth.GetOAuth2MetadataEndpointRedirectHandler(ctx, authContext))

// This option translates HTTP authorization data (cookies) into a gRPC metadata field
gwmuxOptions = append(gwmuxOptions, runtime.WithMetadata(auth.GetHTTPRequestCookieToMetadataHandler(authContext)))
Expand Down
42 changes: 27 additions & 15 deletions pkg/auth/auth_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ const (

// Please see the comment on the corresponding AuthenticationContext for more information.
type Context struct {
oauth2 *oauth2.Config
claims config.Claims
cookieManager interfaces.CookieHandler
oidcProvider *oidc.Provider
options config.OAuthOptions
userInfoURL *url.URL
baseURL *url.URL
metadataURL *url.URL
httpClient *http.Client
oauth2 *oauth2.Config
claims config.Claims
cookieManager interfaces.CookieHandler
oidcProvider *oidc.Provider
options config.OAuthOptions
userInfoURL *url.URL
baseURL *url.URL
oauth2MetadataURL *url.URL
oidcMetadataURL *url.URL
httpClient *http.Client
}

func (c Context) OAuth2Config() *oauth2.Config {
Expand Down Expand Up @@ -65,8 +66,12 @@ func (c Context) GetBaseURL() *url.URL {
return c.baseURL
}

func (c Context) GetMetadataURL() *url.URL {
return c.metadataURL
func (c Context) GetOAuth2MetadataURL() *url.URL {
return c.oauth2MetadataURL
}

func (c Context) GetOIdCMetadataURL() *url.URL {
return c.oidcMetadataURL
}

const (
Expand Down Expand Up @@ -129,14 +134,21 @@ func NewAuthenticationContext(ctx context.Context, options config.OAuthOptions)
logger.Infof(ctx, "Base IDP URL is %s", base)
result.baseURL = base

metadataURL, err := url.Parse(MetadataEndpoint)
result.oauth2MetadataURL, err = url.Parse(OAuth2MetadataEndpoint)
if err != nil {
logger.Errorf(ctx, "Error parsing oauth2 metadata URL %s", err)
return Context{}, errors.Wrapf(ErrAuthContext, err, "Error parsing metadata URL")
}

logger.Infof(ctx, "Metadata endpoint is %s", result.oauth2MetadataURL)

result.oidcMetadataURL, err = url.Parse(OIdCMetadataEndpoint)
if err != nil {
logger.Errorf(ctx, "Error parsing metadata URL %s", err)
logger.Errorf(ctx, "Error parsing oidc metadata URL %s", err)
return Context{}, errors.Wrapf(ErrAuthContext, err, "Error parsing metadata URL")
}

logger.Infof(ctx, "Metadata endpoint is %s", metadataURL)
result.metadataURL = metadataURL
logger.Infof(ctx, "Metadata endpoint is %s", result.oidcMetadataURL)

// Construct the URL object for the user info endpoint if applicable
if options.IdpUserInfoEndpoint != "" {
Expand Down
6 changes: 5 additions & 1 deletion pkg/auth/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ const BearerScheme = "Bearer"

// https://tools.ietf.org/html/rfc8414
// This should be defined without a leading slash. If there is one, the url library's ResolveReference will make it a root path
const MetadataEndpoint = ".well-known/oauth-authorization-server"
const OAuth2MetadataEndpoint = ".well-known/oauth-authorization-server"

// https://openid.net/specs/openid-connect-discovery-1_0.html
// This should be defined without a leading slash. If there is one, the url library's ResolveReference will make it a root path
const OIdCMetadataEndpoint = ".well-known/openid-configuration"
13 changes: 11 additions & 2 deletions pkg/auth/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,18 @@ func GetMeEndpointHandler(ctx context.Context, authCtx interfaces.Authentication

// This returns a handler that will redirect (303) to the well-known metadata endpoint for the OAuth2 authorization server
// See https://tools.ietf.org/html/rfc8414 for more information.
func GetMetadataEndpointRedirectHandler(ctx context.Context, authCtx interfaces.AuthenticationContext) http.HandlerFunc {
func GetOAuth2MetadataEndpointRedirectHandler(ctx context.Context, authCtx interfaces.AuthenticationContext) http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
metadataURL := authCtx.GetBaseURL().ResolveReference(authCtx.GetMetadataURL())
metadataURL := authCtx.GetBaseURL().ResolveReference(authCtx.GetOAuth2MetadataURL())
http.Redirect(writer, request, metadataURL.String(), http.StatusSeeOther)
}
}

// This returns a handler that will redirect (303) to the well-known metadata endpoint for the OAuth2 authorization server
// See https://tools.ietf.org/html/rfc8414 for more information.
func GetOIdCMetadataEndpointRedirectHandler(ctx context.Context, authCtx interfaces.AuthenticationContext) http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
metadataURL := authCtx.GetBaseURL().ResolveReference(authCtx.GetOIdCMetadataURL())
http.Redirect(writer, request, metadataURL.String(), http.StatusSeeOther)
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/auth/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func TestGetMetadataEndpointRedirectHandler(t *testing.T) {
ctx := context.Background()
baseURL, err := url.Parse("http://www.google.com")
assert.NoError(t, err)
metadataPath, err := url.Parse(MetadataEndpoint)
metadataPath, err := url.Parse(OIdCMetadataEndpoint)
assert.NoError(t, err)
mockAuthCtx := mocks.AuthenticationContext{}
mockAuthCtx.On("GetBaseURL").Return(baseURL)
Expand Down
3 changes: 2 additions & 1 deletion pkg/auth/interfaces/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type AuthenticationContext interface {
Options() config.OAuthOptions
GetUserInfoURL() *url.URL
GetBaseURL() *url.URL
GetMetadataURL() *url.URL
GetOAuth2MetadataURL() *url.URL
GetOIdCMetadataURL() *url.URL
GetHTTPClient() *http.Client
}
56 changes: 45 additions & 11 deletions pkg/auth/interfaces/mocks/authentication_context.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/config/third_party_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ type ThirdPartyConfigOptions struct {
}

type FlyteClientConfig struct {
ClientID string `json:"clientId" pflag:",public identifier for the app which handles authorization for a Flyte deployment"`
RedirectURI string `json:"redirectUri" pflag:",This is the callback uri registered with the app which handles authorization for a Flyte deployment"`
ClientID string `json:"clientId" pflag:",public identifier for the app which handles authorization for a Flyte deployment"`
RedirectURI string `json:"redirectUri" pflag:",This is the callback uri registered with the app which handles authorization for a Flyte deployment"`
}
6 changes: 5 additions & 1 deletion pkg/rpc/config/flyte_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,26 @@ import (
const (
clientID = "client_id"
redirectURI = "redirect_uri"
scopes = "scopes"
authMetadataKey = "authorization_metadata_key"
)

func HandleFlyteCliConfigFunc(ctx context.Context, cfg *config.ServerConfig) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
configValues := map[string]string{
configValues := map[string]interface{}{
clientID: cfg.ThirdPartyConfig.FlyteClientConfig.ClientID,
redirectURI: cfg.ThirdPartyConfig.FlyteClientConfig.RedirectURI,
scopes: cfg.Security.Oauth.Scopes,
authMetadataKey: cfg.Security.Oauth.GrpcAuthorizationHeader,
}

configJSON, err := json.Marshal(configValues)
if err != nil {
logger.Infof(ctx, "Failed to marshal flyte_client config to JSON with err: %v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}

_, err = w.Write(configJSON)
if err != nil {
logger.Warningf(ctx, "Failed to write config json [%+v] with err: %v", string(configJSON), err)
Expand Down

0 comments on commit 28ff50d

Please sign in to comment.