Skip to content
Snippets Groups Projects
Commit 4bca9815 authored by Samuel Lang's avatar Samuel Lang Committed by Bruno Oliveira da Silva
Browse files

[KEYCLOAK-9703] Add client auth method option to gatekeeper config

Gatekeeper is still uses go-oidc v1, which makes Gatekeeper to send
auth-code to exchange for access token at server's token endpoint
with both client-authentication methods: basic and post.

As soon as Gatekeeper gets an upgrade to go-oidc v2 this commit no
longer will be necessary.
parent cdfb2a93
Branches
No related tags found
No related merge requests found
......@@ -35,6 +35,7 @@ func newDefaultConfig() *Config {
return &Config{
AccessTokenDuration: time.Duration(720) * time.Hour,
ClientAuthMethod: authMethodBasic,
CookieAccessName: accessCookie,
CookieRefreshName: refreshCookie,
EnableAuthorizationCookies: true,
......@@ -189,6 +190,9 @@ func (r *Config) isValid() error {
return fmt.Errorf("the store url is invalid, error: %s", err)
}
}
if r.ClientAuthMethod != authMethodBasic && r.ClientAuthMethod != authMethodBody {
return fmt.Errorf("invalid client auth method %q (valid values: %s, %s)", r.ClientAuthMethod, authMethodBasic, authMethodBody)
}
}
// check: ensure each of the resource are valid
for _, resource := range r.Resources {
......
......@@ -36,11 +36,13 @@ func TestIsConfig(t *testing.T) {
{
Config: &Config{
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
},
},
{
Config: &Config{
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
},
......@@ -49,6 +51,7 @@ func TestIsConfig(t *testing.T) {
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
......@@ -58,6 +61,7 @@ func TestIsConfig(t *testing.T) {
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
......@@ -68,6 +72,7 @@ func TestIsConfig(t *testing.T) {
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
......@@ -81,6 +86,7 @@ func TestIsConfig(t *testing.T) {
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
......@@ -93,6 +99,7 @@ func TestIsConfig(t *testing.T) {
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
......@@ -105,6 +112,7 @@ func TestIsConfig(t *testing.T) {
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
......@@ -129,6 +137,7 @@ func TestIsConfig(t *testing.T) {
{
Config: &Config{
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
......@@ -141,6 +150,7 @@ func TestIsConfig(t *testing.T) {
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
......@@ -152,6 +162,7 @@ func TestIsConfig(t *testing.T) {
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
......@@ -164,6 +175,7 @@ func TestIsConfig(t *testing.T) {
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
......@@ -177,6 +189,7 @@ func TestIsConfig(t *testing.T) {
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientAuthMethod: "secret-basic",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "https://120.0.0.1",
......
......@@ -70,6 +70,8 @@ const (
unsecureScheme = "http"
secureScheme = "https"
anyMethod = "ANY"
authMethodBasic = "secret-basic"
authMethodBody = "secret-body"
_ contextKey = iota
contextScopeName
......@@ -248,6 +250,8 @@ type Config struct {
// AccessTokenDuration is default duration applied to the access token cookie
AccessTokenDuration time.Duration `json:"access-token-duration" yaml:"access-token-duration" usage:"fallback cookie duration for the access token when using refresh tokens"`
// ClientAuthMethod defines the method for authenticating the oauth client to the server
ClientAuthMethod string `json:"client-auth-method" yaml:"client-auth-method" usage:"the auth method to use with oauth (secret-basic, secret-body)" env:"CLIENT_AUTH_METHOD"`
// CookieDomain is a list of domains the cookie is available to
CookieDomain string `json:"cookie-domain" yaml:"cookie-domain" usage:"domain the access cookie is available to, defaults host header"`
// CookieAccessName is the name of the access cookie holding the access token
......
......@@ -71,7 +71,7 @@ func (r *oauthProxy) oauthAuthorizationHandler(w http.ResponseWriter, req *http.
w.WriteHeader(http.StatusNotAcceptable)
return
}
client, err := r.getOAuthClient(r.getRedirectionURL(w, req))
client, err := r.getOAuthClient(r.getRedirectionURL(w, req), getClientAuthMethod(r.config.ClientAuthMethod))
if err != nil {
r.log.Error("failed to retrieve the oauth client for authorization", zap.Error(err))
w.WriteHeader(http.StatusInternalServerError)
......@@ -103,6 +103,18 @@ func (r *oauthProxy) oauthAuthorizationHandler(w http.ResponseWriter, req *http.
r.redirectToURL(authURL, w, req, http.StatusTemporaryRedirect)
}
// getClientAuthMethod maps the config value CLIENT_AUTH_METHOD to valid OAuth2 auth method keys
func getClientAuthMethod(authMethod string) string {
switch authMethod {
case authMethodBasic:
return oauth2.AuthMethodClientSecretBasic
case authMethodBody:
return oauth2.AuthMethodClientSecretPost
default:
return ""
}
}
// oauthCallbackHandler is responsible for handling the response from oauth service
func (r *oauthProxy) oauthCallbackHandler(w http.ResponseWriter, req *http.Request) {
if r.config.SkipTokenVerification {
......@@ -116,7 +128,7 @@ func (r *oauthProxy) oauthCallbackHandler(w http.ResponseWriter, req *http.Reque
return
}
client, err := r.getOAuthClient(r.getRedirectionURL(w, req))
client, err := r.getOAuthClient(r.getRedirectionURL(w, req), getClientAuthMethod(r.config.ClientAuthMethod))
if err != nil {
r.log.Error("unable to create a oauth2 client", zap.Error(err))
w.WriteHeader(http.StatusInternalServerError)
......
......@@ -30,13 +30,13 @@ import (
)
// getOAuthClient returns a oauth2 client from the openid client
func (r *oauthProxy) getOAuthClient(redirectionURL string) (*oauth2.Client, error) {
func (r *oauthProxy) getOAuthClient(redirectionURL string, clientAuthMethod string) (*oauth2.Client, error) {
return oauth2.NewClient(r.idpClient, oauth2.Config{
Credentials: oauth2.ClientCredentials{
ID: r.config.ClientID,
Secret: r.config.ClientSecret,
},
AuthMethod: oauth2.AuthMethodClientSecretBasic,
AuthMethod: clientAuthMethod,
AuthURL: r.idp.AuthEndpoint.String(),
RedirectURL: redirectionURL,
Scope: append(r.config.Scopes, oidc.DefaultScope...),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment