Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add securityDefinitions to the generated OpenAPI spec #14745

Merged
merged 4 commits into from
Jun 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,258 changes: 4,257 additions & 1 deletion api/swagger-spec/openshift-openapi-spec.json

Large diffs are not rendered by default.

28 changes: 19 additions & 9 deletions pkg/authorization/authorizer/scope/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,22 @@ const (
UserFull = UserIndicator + "full"
)

var defaultSupportedScopesMap = map[string]string{
UserInfo: "Read-only access to your user information (including username, identities, and group membership)",
UserAccessCheck: `Read-only access to view your privileges (for example, "can I create builds?")`,
UserListScopedProjects: `Read-only access to list your projects viewable with this token and view their metadata (display name, description, etc.)`,
UserListAllProjects: `Read-only access to list your projects and view their metadata (display name, description, etc.)`,
UserFull: `Full read/write access with all of your permissions`,
}

func DefaultSupportedScopes() []string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this to have a consistent order so use return sets.StringKeySet(defaultSupportedScopesMap).List() (you can store this as a variable if you want to).

sets = "k8s.io/apimachinery/pkg/util/sets"

return sets.StringKeySet(defaultSupportedScopesMap).List()
}

func DefaultSupportedScopesMap() map[string]string {
return defaultSupportedScopesMap
}

// user:<scope name>
type userEvaluator struct{}

Expand All @@ -153,16 +169,10 @@ func (userEvaluator) Validate(scope string) error {

func (userEvaluator) Describe(scope string) (string, string, error) {
switch scope {
case UserInfo:
return "Read-only access to your user information (including username, identities, and group membership)", "", nil
case UserAccessCheck:
return `Read-only access to view your privileges (for example, "can I create builds?")`, "", nil
case UserListScopedProjects:
return `Read-only access to list your projects viewable with this token and view their metadata (display name, description, etc.)`, "", nil
case UserListAllProjects:
return `Read-only access to list your projects and view their metadata (display name, description, etc.)`, "", nil
case UserInfo, UserAccessCheck, UserListScopedProjects, UserListAllProjects:
return defaultSupportedScopesMap[scope], "", nil
case UserFull:
return `Full read/write access with all of your permissions`, `Includes any access you have to escalating resources like secrets`, nil
return defaultSupportedScopesMap[scope], `Includes any access you have to escalating resources like secrets`, nil
default:
return "", "", fmt.Errorf("unrecognized scope: %v", scope)
}
Expand Down
43 changes: 41 additions & 2 deletions pkg/cmd/server/kubernetes/master/master_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,14 @@ import (
kversion "k8s.io/kubernetes/pkg/version"

"github.com/openshift/origin/pkg/api"
"github.com/openshift/origin/pkg/authorization/authorizer/scope"
"github.com/openshift/origin/pkg/cmd/flagtypes"
configapi "github.com/openshift/origin/pkg/cmd/server/api"
"github.com/openshift/origin/pkg/cmd/server/cm"
"github.com/openshift/origin/pkg/cmd/server/crypto"
"github.com/openshift/origin/pkg/cmd/server/election"
cmdflags "github.com/openshift/origin/pkg/cmd/util/flags"
oauthutil "github.com/openshift/origin/pkg/oauth/util"
openapigenerated "github.com/openshift/origin/pkg/openapi"
securityapi "github.com/openshift/origin/pkg/security/apis/security"
"github.com/openshift/origin/pkg/version"
Expand Down Expand Up @@ -441,7 +443,7 @@ func buildKubeApiserverConfig(
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName)
genericConfig.AdmissionControl = admissionControl
genericConfig.RequestContextMapper = requestContextMapper
genericConfig.OpenAPIConfig = DefaultOpenAPIConfig()
genericConfig.OpenAPIConfig = DefaultOpenAPIConfig(masterConfig)
genericConfig.SwaggerConfig = apiserver.DefaultSwaggerConfig()
genericConfig.SwaggerConfig.PostBuildHandler = customizeSwaggerDefinition
_, loopbackClientConfig, err := configapi.GetInternalKubeClient(masterConfig.MasterClients.OpenShiftLoopbackKubeConfig, masterConfig.MasterClients.OpenShiftLoopbackClientConnectionOverrides)
Expand Down Expand Up @@ -606,7 +608,43 @@ func BuildKubernetesMasterConfig(
return kmaster, nil
}

func DefaultOpenAPIConfig() *openapicommon.Config {
func DefaultOpenAPIConfig(config configapi.MasterConfig) *openapicommon.Config {
securityDefinitions := spec.SecurityDefinitions{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure where to source the right info, for example about flow type and scopes, and no other code in the origin repo uses the oauth2 type yet, it seem any outh based on any kind of token is defined just as an apikey bearer token...

if len(config.ServiceAccountConfig.PublicKeyFiles) > 0 {
securityDefinitions["BearerToken"] = &spec.SecurityScheme{
SecuritySchemeProps: spec.SecuritySchemeProps{
Type: "apiKey",
Name: "authorization",
In: "header",
Description: "Bearer Token authentication",
},
}
}
if config.OAuthConfig != nil {
baseUrl := config.OAuthConfig.MasterPublicURL
securityDefinitions["Oauth2Implicit"] = &spec.SecurityScheme{
SecuritySchemeProps: spec.SecuritySchemeProps{
Type: "oauth2",
Flow: "implicit",
AuthorizationURL: oauthutil.OpenShiftOAuthAuthorizeURL(baseUrl),
Scopes: scope.DefaultSupportedScopesMap(),
},
}
securityDefinitions["Oauth2AccessToken"] = &spec.SecurityScheme{
SecuritySchemeProps: spec.SecuritySchemeProps{
Type: "oauth2",
Flow: "accessCode",
AuthorizationURL: oauthutil.OpenShiftOAuthAuthorizeURL(baseUrl),
TokenURL: oauthutil.OpenShiftOAuthTokenURL(baseUrl),
Scopes: scope.DefaultSupportedScopesMap(),
},
}
}
if configapi.UseTLS(config.ServingInfo.ServingInfo) {
// No support in Swagger's OpenAPI sepc v.2 ¯\_(ツ)_/¯
// TODO: Add x509 specification once available
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have a separate GitHub issue to track this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@simo5 tag the issue you opened here.

}

return &openapicommon.Config{
GetDefinitions: openapigenerated.GetOpenAPIDefinitions,
IgnorePrefixes: []string{"/swaggerapi", "/healthz", "/controllers", "/metrics", "/version/openshift", "/brokers"},
Expand Down Expand Up @@ -708,6 +746,7 @@ func DefaultOpenAPIConfig() *openapicommon.Config {
Description: "Default Response.",
},
},
SecurityDefinitions: &securityDefinitions,
}
}

Expand Down
5 changes: 3 additions & 2 deletions pkg/cmd/server/origin/asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
configapi "github.com/openshift/origin/pkg/cmd/server/api"
"github.com/openshift/origin/pkg/cmd/server/crypto"
cmdutil "github.com/openshift/origin/pkg/cmd/util"
oauthutil "github.com/openshift/origin/pkg/oauth/util"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This package dependency was previously excluded intentionally. The asset server should not depend on the oauth package at all. The two are logically independent.

oversion "github.com/openshift/origin/pkg/version"
)

Expand Down Expand Up @@ -217,8 +218,8 @@ func (c *AssetConfig) addHandlers(handler http.Handler) (http.Handler, error) {
KubernetesAddr: masterURL.Host,
KubernetesPrefix: server.DefaultLegacyAPIPrefix,
KubernetesResources: k8sResources.List(),
OAuthAuthorizeURI: OpenShiftOAuthAuthorizeURL(masterURL.String()),
OAuthTokenURI: OpenShiftOAuthTokenURL(masterURL.String()),
OAuthAuthorizeURI: oauthutil.OpenShiftOAuthAuthorizeURL(masterURL.String()),
OAuthTokenURI: oauthutil.OpenShiftOAuthTokenURL(masterURL.String()),
OAuthRedirectBase: c.Options.PublicURL,
OAuthClientID: OpenShiftWebConsoleClientID,
LogoutURI: c.Options.LogoutURL,
Expand Down
32 changes: 11 additions & 21 deletions pkg/cmd/server/origin/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ import (
clientauthetcd "github.com/openshift/origin/pkg/oauth/registry/oauthclientauthorization/etcd"
"github.com/openshift/origin/pkg/oauth/server/osinserver"
"github.com/openshift/origin/pkg/oauth/server/osinserver/registrystorage"
oauthutil "github.com/openshift/origin/pkg/oauth/util"
saoauth "github.com/openshift/origin/pkg/serviceaccounts/oauthclient"
)

const (
OpenShiftOAuthAPIPrefix = "/oauth"
openShiftLoginPrefix = "/login"
openShiftApproveSubpath = "approve"
OpenShiftOAuthCallbackPrefix = "/oauth2callback"
Expand Down Expand Up @@ -155,7 +155,7 @@ func (c *AuthConfig) WithOAuth(handler http.Handler) (http.Handler, error) {
},
osinserver.NewDefaultErrorHandler(),
)
server.Install(mux, OpenShiftOAuthAPIPrefix)
server.Install(mux, oauthutil.OpenShiftOAuthAPIPrefix)

if err := CreateOrUpdateDefaultOAuthClients(c.Options.MasterPublicURL, c.AssetPublicAddresses, clientRegistry); err != nil {
glog.Fatal(err)
Expand All @@ -165,7 +165,7 @@ func (c *AuthConfig) WithOAuth(handler http.Handler) (http.Handler, error) {
glog.Fatal(err)
}
osOAuthClientConfig := c.NewOpenShiftOAuthClientConfig(browserClient)
osOAuthClientConfig.RedirectUrl = c.Options.MasterPublicURL + path.Join(OpenShiftOAuthAPIPrefix, tokenrequest.DisplayTokenEndpoint)
osOAuthClientConfig.RedirectUrl = c.Options.MasterPublicURL + path.Join(oauthutil.OpenShiftOAuthAPIPrefix, tokenrequest.DisplayTokenEndpoint)

osOAuthClient, _ := osincli.NewClient(osOAuthClientConfig)
if len(*c.Options.MasterCA) > 0 {
Expand All @@ -180,7 +180,7 @@ func (c *AuthConfig) WithOAuth(handler http.Handler) (http.Handler, error) {
}

tokenRequestEndpoints := tokenrequest.NewEndpoints(c.Options.MasterPublicURL, osOAuthClient)
tokenRequestEndpoints.Install(mux, OpenShiftOAuthAPIPrefix)
tokenRequestEndpoints.Install(mux, oauthutil.OpenShiftOAuthAPIPrefix)

// glog.Infof("oauth server configured as: %#v", server)
// glog.Infof("auth handler: %#v", authHandler)
Expand Down Expand Up @@ -224,23 +224,13 @@ func (c *AuthConfig) NewOpenShiftOAuthClientConfig(client *oauthapi.OAuthClient)
ClientSecret: client.Secret,
ErrorsInStatusCode: true,
SendClientSecretInParams: true,
AuthorizeUrl: OpenShiftOAuthAuthorizeURL(c.Options.MasterPublicURL),
TokenUrl: OpenShiftOAuthTokenURL(c.Options.MasterURL),
AuthorizeUrl: oauthutil.OpenShiftOAuthAuthorizeURL(c.Options.MasterPublicURL),
TokenUrl: oauthutil.OpenShiftOAuthTokenURL(c.Options.MasterURL),
Scope: "",
}
return config
}

func OpenShiftOAuthAuthorizeURL(masterAddr string) string {
return masterAddr + path.Join(OpenShiftOAuthAPIPrefix, osinserver.AuthorizePath)
}
func OpenShiftOAuthTokenURL(masterAddr string) string {
return masterAddr + path.Join(OpenShiftOAuthAPIPrefix, osinserver.TokenPath)
}
func OpenShiftOAuthTokenRequestURL(masterAddr string) string {
return masterAddr + path.Join(OpenShiftOAuthAPIPrefix, tokenrequest.RequestTokenEndpoint)
}

func ensureOAuthClient(client oauthapi.OAuthClient, clientRegistry clientregistry.Registry, preserveExistingRedirects, preserveExistingSecret bool) error {
ctx := apirequest.NewContext()
_, err := clientRegistry.CreateClient(ctx, &client)
Expand Down Expand Up @@ -306,7 +296,7 @@ func CreateOrUpdateDefaultOAuthClients(masterPublicAddr string, assetPublicAddre
ObjectMeta: metav1.ObjectMeta{Name: OpenShiftBrowserClientID},
Secret: uuid.New(),
RespondWithChallenges: false,
RedirectURIs: []string{masterPublicAddr + path.Join(OpenShiftOAuthAPIPrefix, tokenrequest.DisplayTokenEndpoint)},
RedirectURIs: []string{masterPublicAddr + path.Join(oauthutil.OpenShiftOAuthAPIPrefix, tokenrequest.DisplayTokenEndpoint)},
GrantMethod: oauthapi.GrantHandlerAuto,
}
if err := ensureOAuthClient(browserClient, clientRegistry, true, true); err != nil {
Expand All @@ -319,7 +309,7 @@ func CreateOrUpdateDefaultOAuthClients(masterPublicAddr string, assetPublicAddre
ObjectMeta: metav1.ObjectMeta{Name: OpenShiftCLIClientID},
Secret: "",
RespondWithChallenges: true,
RedirectURIs: []string{masterPublicAddr + path.Join(OpenShiftOAuthAPIPrefix, tokenrequest.ImplicitTokenEndpoint)},
RedirectURIs: []string{masterPublicAddr + path.Join(oauthutil.OpenShiftOAuthAPIPrefix, tokenrequest.ImplicitTokenEndpoint)},
GrantMethod: oauthapi.GrantHandlerAuto,
}
if err := ensureOAuthClient(cliClient, clientRegistry, false, false); err != nil {
Expand Down Expand Up @@ -360,7 +350,7 @@ func (c *AuthConfig) getGrantHandler(mux cmdutil.Mux, auth authenticator.Request
// Since any OAuth client could require prompting, we will unconditionally
// start the GrantServer here.
grantServer := grant.NewGrant(c.getCSRF(), auth, grant.DefaultFormRenderer, clientregistry, authregistry)
grantServer.Install(mux, path.Join(OpenShiftOAuthAPIPrefix, osinserver.AuthorizePath, openShiftApproveSubpath))
grantServer.Install(mux, path.Join(oauthutil.OpenShiftOAuthAPIPrefix, osinserver.AuthorizePath, openShiftApproveSubpath))

// Set defaults for standard clients. These can be overridden.
return handlers.NewPerClientGrant(
Expand Down Expand Up @@ -497,7 +487,7 @@ func (c *AuthConfig) getAuthenticationHandler(mux cmdutil.Mux, errorHandler hand
}
} else if requestHeaderProvider, isRequestHeader := identityProvider.Provider.(*configapi.RequestHeaderIdentityProvider); isRequestHeader {
// We might be redirecting to an external site, we need to fully resolve the request URL to the public master
baseRequestURL, err := url.Parse(c.Options.MasterPublicURL + OpenShiftOAuthAPIPrefix + osinserver.AuthorizePath)
baseRequestURL, err := url.Parse(c.Options.MasterPublicURL + oauthutil.OpenShiftOAuthAPIPrefix + osinserver.AuthorizePath)
if err != nil {
return nil, err
}
Expand All @@ -512,7 +502,7 @@ func (c *AuthConfig) getAuthenticationHandler(mux cmdutil.Mux, errorHandler hand

if redirectors.Count() > 0 && len(challengers) == 0 {
// Add a default challenger that will warn and give a link to the web browser token-granting location
challengers["placeholder"] = placeholderchallenger.New(OpenShiftOAuthTokenRequestURL(c.Options.MasterPublicURL))
challengers["placeholder"] = placeholderchallenger.New(oauthutil.OpenShiftOAuthTokenRequestURL(c.Options.MasterPublicURL))
}

var selectProviderTemplateFile string
Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/server/origin/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
serverhandlers "github.com/openshift/origin/pkg/cmd/server/handlers"
cmdutil "github.com/openshift/origin/pkg/cmd/util"
"github.com/openshift/origin/pkg/cmd/util/plug"
oauthutil "github.com/openshift/origin/pkg/oauth/util"
routeplugin "github.com/openshift/origin/pkg/route/allocation/simple"
routeallocationcontroller "github.com/openshift/origin/pkg/route/controller/allocation"
sccstorage "github.com/openshift/origin/pkg/security/registry/securitycontextconstraints/etcd"
Expand Down Expand Up @@ -179,7 +180,7 @@ func (c *MasterConfig) Run(kubeAPIServerConfig *kubeapiserver.Config, assetConfi

func (c *MasterConfig) buildHandlerChain(assetConfig *AssetConfig) (func(http.Handler, *apiserver.Config) (secure http.Handler), error) {
if c.Options.OAuthConfig != nil {
glog.Infof("Starting OAuth2 API at %s", OpenShiftOAuthAPIPrefix)
glog.Infof("Starting OAuth2 API at %s", oauthutil.OpenShiftOAuthAPIPrefix)
}

if assetConfig != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/cmd/server/origin/nonapiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
"github.com/openshift/origin/pkg/cmd/util/plug"
"github.com/openshift/origin/pkg/oauth/discovery"
oauthutil "github.com/openshift/origin/pkg/oauth/util"
openservicebrokerserver "github.com/openshift/origin/pkg/openservicebroker/server"
templateapi "github.com/openshift/origin/pkg/template/apis/template"
templateinformer "github.com/openshift/origin/pkg/template/generated/informers/internalversion"
Expand Down Expand Up @@ -106,7 +106,7 @@ const (
// masterPublicURL should be internally and externally routable to allow all users to discover this information
func initOAuthAuthorizationServerMetadataRoute(mux *genericmux.PathRecorderMux, path, masterPublicURL string) {
// Build OAuth metadata once
metadata, err := json.MarshalIndent(discovery.Get(masterPublicURL, OpenShiftOAuthAuthorizeURL(masterPublicURL), OpenShiftOAuthTokenURL(masterPublicURL)), "", " ")
metadata, err := json.MarshalIndent(oauthutil.GetOauthMetadata(masterPublicURL), "", " ")
if err != nil {
glog.Errorf("Unable to initialize OAuth authorization server metadata route: %v", err)
return
Expand Down
17 changes: 6 additions & 11 deletions pkg/oauth/discovery/discovery.go → pkg/oauth/util/discovery.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package discovery
package util

import (
"github.com/RangelReale/osin"
Expand Down Expand Up @@ -38,19 +38,14 @@ type OauthAuthorizationServerMetadata struct {
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
}

func Get(masterPublicURL, authorizeURL, tokenURL string) OauthAuthorizationServerMetadata {
func GetOauthMetadata(masterPublicURL string) OauthAuthorizationServerMetadata {
config := osinserver.NewDefaultServerConfig()
return OauthAuthorizationServerMetadata{
Issuer: masterPublicURL,
AuthorizationEndpoint: authorizeURL,
TokenEndpoint: tokenURL,
ScopesSupported: []string{ // Note: this list is incomplete, which is allowed per the draft spec
scope.UserFull,
scope.UserInfo,
scope.UserAccessCheck,
scope.UserListScopedProjects,
scope.UserListAllProjects,
},
AuthorizationEndpoint: OpenShiftOAuthAuthorizeURL(masterPublicURL),
TokenEndpoint: OpenShiftOAuthTokenURL(masterPublicURL),
// Note: this list is incomplete, which is allowed per the draft spec
ScopesSupported: scope.DefaultSupportedScopes(),
ResponseTypesSupported: config.AllowedAuthorizeTypes,
GrantTypesSupported: osin.AllowedAccessType{osin.AUTHORIZATION_CODE, osin.AccessRequestType("implicit")}, // TODO use config.AllowedAccessTypes once our implementation handles other grant types
CodeChallengeMethodsSupported: validation.CodeChallengeMethodsSupported,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package discovery
package util

import (
"reflect"
Expand All @@ -7,18 +7,18 @@ import (
"github.com/RangelReale/osin"
)

func TestGet(t *testing.T) {
actual := Get("https://localhost:8443", "https://localhost:8443/oauth/authorize", "https://localhost:8443/oauth/token")
func TestGetOauthMetadata(t *testing.T) {
actual := GetOauthMetadata("https://localhost:8443")
expected := OauthAuthorizationServerMetadata{
Issuer: "https://localhost:8443",
AuthorizationEndpoint: "https://localhost:8443/oauth/authorize",
TokenEndpoint: "https://localhost:8443/oauth/token",
ScopesSupported: []string{
"user:check-access",
"user:full",
"user:info",
"user:check-access",
"user:list-scoped-projects",
"user:list-projects",
"user:list-scoped-projects",
},
ResponseTypesSupported: osin.AllowedAuthorizeType{
"code",
Expand Down
22 changes: 22 additions & 0 deletions pkg/oauth/util/url.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package util

import (
"path"

"github.com/openshift/origin/pkg/auth/server/tokenrequest"
"github.com/openshift/origin/pkg/oauth/server/osinserver"
)

const (
OpenShiftOAuthAPIPrefix = "/oauth"
)

func OpenShiftOAuthAuthorizeURL(masterAddr string) string {
return masterAddr + path.Join(OpenShiftOAuthAPIPrefix, osinserver.AuthorizePath)
}
func OpenShiftOAuthTokenURL(masterAddr string) string {
return masterAddr + path.Join(OpenShiftOAuthAPIPrefix, osinserver.TokenPath)
}
func OpenShiftOAuthTokenRequestURL(masterAddr string) string {
return masterAddr + path.Join(OpenShiftOAuthAPIPrefix, tokenrequest.RequestTokenEndpoint)
}
4 changes: 2 additions & 2 deletions test/integration/auth_proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
ktransport "k8s.io/client-go/transport"

configapi "github.com/openshift/origin/pkg/cmd/server/api"
"github.com/openshift/origin/pkg/cmd/server/origin"
oauthapi "github.com/openshift/origin/pkg/oauth/apis/oauth"
oauthutil "github.com/openshift/origin/pkg/oauth/util"
testutil "github.com/openshift/origin/test/util"
testserver "github.com/openshift/origin/test/util/server"
)
Expand Down Expand Up @@ -66,7 +66,7 @@ func TestAuthProxyOnAuthorize(t *testing.T) {
}

// our simple URL to get back a code. We want to go through the front proxy
rawAuthorizeRequest := proxyServer.URL + origin.OpenShiftOAuthAPIPrefix + "/authorize?response_type=code&client_id=test"
rawAuthorizeRequest := proxyServer.URL + oauthutil.OpenShiftOAuthAPIPrefix + "/authorize?response_type=code&client_id=test"

// the first request we make to the front proxy should challenge us for authentication info
shouldBeAChallengeResponse, err := http.Get(rawAuthorizeRequest)
Expand Down