func (c *AuthConfig) getAuthenticationRequestHandler() (authenticator.Request, error) { var authRequestHandlers []authenticator.Request if c.SessionAuth != nil { authRequestHandlers = append(authRequestHandlers, c.SessionAuth) } for _, identityProvider := range c.Options.IdentityProviders { identityMapper := identitymapper.NewAlwaysCreateUserIdentityToUserMapper(c.IdentityRegistry, c.UserRegistry) if configapi.IsPasswordAuthenticator(identityProvider) { passwordAuthenticator, err := c.getPasswordAuthenticator(identityProvider) if err != nil { return nil, err } authRequestHandlers = append(authRequestHandlers, basicauthrequest.NewBasicAuthAuthentication(passwordAuthenticator, true)) } else { switch provider := identityProvider.Provider.Object.(type) { case (*configapi.RequestHeaderIdentityProvider): var authRequestHandler authenticator.Request authRequestConfig := &headerrequest.Config{ UserNameHeaders: provider.Headers, } authRequestHandler = headerrequest.NewAuthenticator(identityProvider.Name, authRequestConfig, identityMapper) // Wrap with an x509 verifier if len(provider.ClientCA) > 0 { caData, err := ioutil.ReadFile(provider.ClientCA) if err != nil { return nil, fmt.Errorf("Error reading %s: %v", provider.ClientCA, err) } opts := x509request.DefaultVerifyOptions() opts.Roots = x509.NewCertPool() if ok := opts.Roots.AppendCertsFromPEM(caData); !ok { return nil, fmt.Errorf("Error loading certs from %s: %v", provider.ClientCA, err) } authRequestHandler = x509request.NewVerifier(opts, authRequestHandler) } authRequestHandlers = append(authRequestHandlers, authRequestHandler) } } } authRequestHandler := unionrequest.NewUnionAuthentication(authRequestHandlers...) return authRequestHandler, nil }
func TestAuthProxyOnAuthorize(t *testing.T) { testutil.DeleteAllEtcdKeys() // setup etcdClient := testutil.NewEtcdClient() etcdHelper, _ := master.NewEtcdHelper(etcdClient, latest.Version, etcdtest.PathPrefix()) accessTokenStorage := accesstokenetcd.NewREST(etcdHelper) accessTokenRegistry := accesstokenregistry.NewRegistry(accessTokenStorage) authorizeTokenStorage := authorizetokenetcd.NewREST(etcdHelper) authorizeTokenRegistry := authorizetokenregistry.NewRegistry(authorizeTokenStorage) clientStorage := clientetcd.NewREST(etcdHelper) clientRegistry := clientregistry.NewRegistry(clientStorage) clientAuthStorage := clientauthetcd.NewREST(etcdHelper) clientAuthRegistry := clientauthregistry.NewRegistry(clientAuthStorage) userStorage := useretcd.NewREST(etcdHelper) userRegistry := userregistry.NewRegistry(userStorage) identityStorage := identityetcd.NewREST(etcdHelper) identityRegistry := identityregistry.NewRegistry(identityStorage) identityMapper := identitymapper.NewAlwaysCreateUserIdentityToUserMapper(identityRegistry, userRegistry) // this auth request handler is the one that is supposed to recognize information from a front proxy authRequestHandler := headerrequest.NewAuthenticator("front-proxy-test", headerrequest.NewDefaultConfig(), identityMapper) authHandler := &oauthhandlers.EmptyAuth{} storage := registrystorage.New(accessTokenRegistry, authorizeTokenRegistry, clientRegistry, oauthregistry.NewUserConversion()) config := osinserver.NewDefaultServerConfig() grantChecker := oauthregistry.NewClientAuthorizationGrantChecker(clientAuthRegistry) grantHandler := oauthhandlers.NewAutoGrant() server := osinserver.New( config, storage, osinserver.AuthorizeHandlers{ oauthhandlers.NewAuthorizeAuthenticator( authRequestHandler, authHandler, oauthhandlers.EmptyError{}, ), oauthhandlers.NewGrantCheck( grantChecker, grantHandler, oauthhandlers.EmptyError{}, ), }, osinserver.AccessHandlers{ oauthhandlers.NewDenyAccessAuthenticator(), }, osinserver.NewDefaultErrorHandler(), ) mux := http.NewServeMux() server.Install(mux, origin.OpenShiftOAuthAPIPrefix) oauthServer := httptest.NewServer(http.Handler(mux)) defer oauthServer.Close() t.Logf("oauth server is on %v\n", oauthServer.URL) // set up a front proxy guarding the oauth server proxyHTTPHandler := NewBasicAuthChallenger("TestRegistryAndServer", validUsers, NewXRemoteUserProxyingHandler(oauthServer.URL)) proxyServer := httptest.NewServer(proxyHTTPHandler) defer proxyServer.Close() t.Logf("proxy server is on %v\n", proxyServer.URL) // need to prime clients so that we can get back a code. the client must be valid createClient(t, clientRegistry, &oauthapi.OAuthClient{ObjectMeta: kapi.ObjectMeta{Name: "test"}, Secret: "secret", RedirectURIs: []string{oauthServer.URL}}) // 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" // the first request we make to the front proxy should challenge us for authentication info shouldBeAChallengeResponse, err := http.Get(rawAuthorizeRequest) if err != nil { t.Errorf("Unexpected error: %v", err) } if shouldBeAChallengeResponse.StatusCode != http.StatusUnauthorized { t.Errorf("Expected Unauthorized, but got %v", shouldBeAChallengeResponse.StatusCode) } // create an http.Client to make our next request. We need a custom Transport to authenticate us through our front proxy // and a custom CheckRedirect so that we can keep track of the redirect responses we're getting // OAuth requests a few redirects that we don't really care about checking, so this simpler than using a round tripper // and manually handling redirects and setting our auth information every time for the front proxy redirectedUrls := make([]url.URL, 10) httpClient := http.Client{ CheckRedirect: getRedirectMethod(t, &redirectedUrls), Transport: kclient.NewBasicAuthRoundTripper("sanefarmer", "who?", http.DefaultTransport), } // make our authorize request again, but this time our transport has properly set the auth info for the front proxy req, err := http.NewRequest("GET", rawAuthorizeRequest, nil) _, err = httpClient.Do(req) if err != nil { t.Errorf("Unexpected error: %v", err) } // check the last redirect and see if we got a code foundCode := "" if len(redirectedUrls) > 0 { foundCode = redirectedUrls[len(redirectedUrls)-1].Query().Get("code") } if len(foundCode) == 0 { t.Errorf("Did not find code in any redirect: %v", redirectedUrls) } else { t.Logf("Found code %v\n", foundCode) } }