mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 18:25:56 +01:00
Merge pull request #10088 from reasonerjt/authproxy-cert-setting
Support pinning to authproxy server's cert
This commit is contained in:
commit
339c1d4cab
2
make/migrations/postgresql/0012_1.9.4_schema.up.sql
Normal file
2
make/migrations/postgresql/0012_1.9.4_schema.up.sql
Normal file
@ -0,0 +1,2 @@
|
||||
/* change the data type to text to accommodate larger data */
|
||||
ALTER TABLE properties ALTER COLUMN v TYPE text;
|
@ -139,6 +139,7 @@ var (
|
||||
{Name: common.HTTPAuthProxyTokenReviewEndpoint, Scope: UserScope, Group: HTTPAuthGroup, ItemType: &StringType{}},
|
||||
{Name: common.HTTPAuthProxyVerifyCert, Scope: UserScope, Group: HTTPAuthGroup, DefaultValue: "true", ItemType: &BoolType{}},
|
||||
{Name: common.HTTPAuthProxySkipSearch, Scope: UserScope, Group: HTTPAuthGroup, DefaultValue: "false", ItemType: &BoolType{}},
|
||||
{Name: common.HTTPAuthProxyServerCertificate, Scope: UserScope, Group: HTTPAuthGroup, ItemType: &StringType{}},
|
||||
{Name: common.HTTPAuthProxyCaseSensitive, Scope: UserScope, Group: HTTPAuthGroup, DefaultValue: "true", ItemType: &BoolType{}},
|
||||
|
||||
{Name: common.OIDCName, Scope: UserScope, Group: OIDCGroup, ItemType: &StringType{}},
|
||||
|
@ -106,6 +106,7 @@ const (
|
||||
HTTPAuthProxyVerifyCert = "http_authproxy_verify_cert"
|
||||
HTTPAuthProxySkipSearch = "http_authproxy_skip_search"
|
||||
HTTPAuthProxyCaseSensitive = "http_authproxy_case_sensitive"
|
||||
HTTPAuthProxyServerCertificate = "http_authproxy_server_certificate"
|
||||
OIDCName = "oidc_name"
|
||||
OIDCEndpoint = "oidc_endpoint"
|
||||
OIDCCLientID = "oidc_client_id"
|
||||
|
@ -73,6 +73,7 @@ type HTTPAuthProxy struct {
|
||||
TokenReviewEndpoint string `json:"tokenreivew_endpoint"`
|
||||
VerifyCert bool `json:"verify_cert"`
|
||||
SkipSearch bool `json:"skip_search"`
|
||||
ServerCertificate string `json:"server_certificate"`
|
||||
CaseSensitive bool `json:"case_sensitive"`
|
||||
}
|
||||
|
||||
|
@ -108,20 +108,8 @@ func TestPutConfigMaxLength(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
apiTest := newHarborAPI()
|
||||
|
||||
// length is 512,expected code: 200
|
||||
// length is 1059,expected code: 200
|
||||
cfg := map[string]interface{}{
|
||||
common.LDAPGroupSearchFilter: "OSWvgTrQJuhiPRZt7eCReNku29vrtMBBD2cZt6jl7LQN4OZQcirqEhS2vCnkW8X1OAHMJxiO1LyEY26j" +
|
||||
"YhBEiUFliPKDUt8Q9endowT3H60nJibEnCkSRVjix7QujXKRzlmvxcOK76v1oZAoWeHSwwtv7tZrOk16Jj5LTGYdLOnZd2LIgBniTKmceL" +
|
||||
"VY5WOgcpmgQCfI5HLbzWsmAqmFfbsDbadirrEDiXYYfZQ0LnF8s6sD4H13eImgenAumXEsBRH43FT37AbNXNxzlaSs8IQYEdPLaMyKoXFb" +
|
||||
"rfa0LPipwXnU7bl54IlWOTXwCwum0JGS4qBiMl6LwKUBle34ObZ9fTLh5dFOVE1GdzrGE0kQ7qUmYjMZafQbSXzV80zTc22aZt3RQa9Gxt" +
|
||||
"Dn2VqtgcoKAiZHkEySStiwOJtZpwuplyy1jcM3DcN0R9b8IidYAWOsriqetUBThqb75XIZTXAaRWhHLw4ayROYiaw8dPuLRjeVKhdyznqq" +
|
||||
"AKxQGyvm",
|
||||
}
|
||||
code200, _ := apiTest.PutConfig(*admin, cfg)
|
||||
assert.Equal(200, code200, "the status code of modifying configurations with admin user should be 200")
|
||||
|
||||
// length is 1059,expected code: 500
|
||||
cfg = map[string]interface{}{
|
||||
common.LDAPGroupSearchFilter: "YU2YcM13JtSx5jtBiftTjfaEM9KZFQ0XA5fKQHU02E9Xe0aLYaSy7YBokrTA8oHFjSkWFSgWZJ6FEmTS" +
|
||||
"Vy5Ovsy5to2kWnFtbVNX3pzbeQpZeAqK3mEGnXdMkMSQu9WTq74s99GpwjEdA628pcZqLx6wCR0IvwryqIcNoRtqPlUcuRGODWA8ZXaC0d" +
|
||||
"Qs7cRUYSe8onHsM2c9JWuUS8Jv4E7KggfytrxeKAT0WGP5DBZsB7rHZKxoAppE3C0NueEeC4yV791PUOODJt9rc0RrcD6ORUIO5RriCwym" +
|
||||
@ -134,6 +122,6 @@ func TestPutConfigMaxLength(t *testing.T) {
|
||||
"kkqQmtFREitKWl5njO8wLJw0XyeIVAej75NsGKKZWVjyaupaM9Bqn6NFrWjELFacLox6OCcRIDSDl3ntNN8tIzGOF7aXVCIqljJl0IL9Pz" +
|
||||
"NenmmubaNm48YjfkBk8MqOUSYJYaFkO1qCKbVdMg7yTqKEHgSUqEkoFPoJMH6GAozC",
|
||||
}
|
||||
code500, _ := apiTest.PutConfig(*admin, cfg)
|
||||
assert.Equal(500, code500, "the status code of modifying configurations with admin user should be 500")
|
||||
sc, _ := apiTest.PutConfig(*admin, cfg)
|
||||
assert.Equal(200, sc, "the status code of modifying configurations with admin user should be 200")
|
||||
}
|
||||
|
@ -16,9 +16,11 @@ package authproxy
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/jobservice/logger"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
@ -39,13 +41,7 @@ import (
|
||||
const refreshDuration = 2 * time.Second
|
||||
const userEntryComment = "By Authproxy"
|
||||
|
||||
var secureTransport = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
}
|
||||
var insecureTransport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
var transport = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
}
|
||||
|
||||
@ -56,7 +52,6 @@ type Auth struct {
|
||||
sync.Mutex
|
||||
Endpoint string
|
||||
TokenReviewEndpoint string
|
||||
SkipCertVerify bool
|
||||
SkipSearch bool
|
||||
// When this attribute is set to false, the name of user/group will be converted to lower-case when onboarded to Harbor, so
|
||||
// as long as the authentication is successful there's no difference in terms of upper or lower case that is used.
|
||||
@ -229,18 +224,30 @@ func (a *Auth) ensure() error {
|
||||
}
|
||||
a.Endpoint = setting.Endpoint
|
||||
a.TokenReviewEndpoint = setting.TokenReviewEndpoint
|
||||
a.SkipCertVerify = !setting.VerifyCert
|
||||
a.SkipSearch = setting.SkipSearch
|
||||
tlsCfg, err := getTLSConfig(setting)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if a.SkipCertVerify {
|
||||
a.client.Transport = insecureTransport
|
||||
} else {
|
||||
a.client.Transport = secureTransport
|
||||
transport.TLSClientConfig = tlsCfg
|
||||
a.client.Transport = transport
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getTLSConfig(setting *models.HTTPAuthProxy) (*tls.Config, error) {
|
||||
c := setting.ServerCertificate
|
||||
if setting.VerifyCert && len(c) > 0 {
|
||||
certs := x509.NewCertPool()
|
||||
if !certs.AppendCertsFromPEM([]byte(c)) {
|
||||
logger.Errorf("Failed to pin server certificate, please double check if it's valid, certificate: %s", c)
|
||||
return nil, fmt.Errorf("failed to pin server certificate for authproxy")
|
||||
}
|
||||
return &tls.Config{RootCAs: certs}, nil
|
||||
}
|
||||
return &tls.Config{InsecureSkipVerify: !setting.VerifyCert}, nil
|
||||
}
|
||||
|
||||
func (a *Auth) normalizeName(n string) string {
|
||||
if !a.CaseSensitive {
|
||||
return strings.ToLower(n)
|
||||
|
@ -15,11 +15,6 @@
|
||||
package authproxy
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/dao/group"
|
||||
@ -29,6 +24,9 @@ import (
|
||||
"github.com/goharbor/harbor/src/core/auth/authproxy/test"
|
||||
"github.com/goharbor/harbor/src/core/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var mockSvr *httptest.Server
|
||||
@ -46,17 +44,14 @@ func TestMain(m *testing.M) {
|
||||
a = &Auth{
|
||||
Endpoint: mockSvr.URL + "/test/login",
|
||||
TokenReviewEndpoint: mockSvr.URL + "/test/tokenreview",
|
||||
SkipCertVerify: true,
|
||||
CaseSensitive: false,
|
||||
// So it won't require mocking the cfgManager
|
||||
settingTimeStamp: time.Now(),
|
||||
}
|
||||
cfgMap := cut.GetUnitTestConfig()
|
||||
conf := map[string]interface{}{
|
||||
common.HTTPAuthProxyEndpoint: a.Endpoint,
|
||||
common.HTTPAuthProxyTokenReviewEndpoint: a.TokenReviewEndpoint,
|
||||
common.HTTPAuthProxyVerifyCert: !a.SkipCertVerify,
|
||||
common.HTTPAuthProxyCaseSensitive: a.CaseSensitive,
|
||||
common.HTTPAuthProxyVerifyCert: false,
|
||||
common.PostGreSQLSSLMode: cfgMap[common.PostGreSQLSSLMode],
|
||||
common.PostGreSQLUsername: cfgMap[common.PostGreSQLUsername],
|
||||
common.PostGreSQLPort: cfgMap[common.PostGreSQLPort],
|
||||
@ -213,3 +208,135 @@ func TestAuth_OnBoardGroup(t *testing.T) {
|
||||
t.Fatal("Empty user group should failed to OnBoard")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTLSConfig(t *testing.T) {
|
||||
type result struct {
|
||||
hasError bool
|
||||
insecure bool
|
||||
nilRootCA bool
|
||||
}
|
||||
cases := []struct {
|
||||
input *models.HTTPAuthProxy
|
||||
expect result
|
||||
}{
|
||||
{
|
||||
input: &models.HTTPAuthProxy{
|
||||
Endpoint: "https://127.0.0.1/login",
|
||||
TokenReviewEndpoint: "https://127.0.0.1/tokenreview",
|
||||
VerifyCert: false,
|
||||
SkipSearch: false,
|
||||
ServerCertificate: "",
|
||||
CaseSensitive: false,
|
||||
},
|
||||
expect: result{
|
||||
hasError: false,
|
||||
insecure: true,
|
||||
nilRootCA: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
input: &models.HTTPAuthProxy{
|
||||
Endpoint: "https://127.0.0.1/login",
|
||||
TokenReviewEndpoint: "https://127.0.0.1/tokenreview",
|
||||
VerifyCert: false,
|
||||
SkipSearch: false,
|
||||
ServerCertificate: "This does not look like a cert",
|
||||
CaseSensitive: false,
|
||||
},
|
||||
expect: result{
|
||||
hasError: false,
|
||||
insecure: true,
|
||||
nilRootCA: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
input: &models.HTTPAuthProxy{
|
||||
Endpoint: "https://127.0.0.1/login",
|
||||
TokenReviewEndpoint: "https://127.0.0.1/tokenreview",
|
||||
VerifyCert: true,
|
||||
SkipSearch: false,
|
||||
ServerCertificate: "This does not look like a cert",
|
||||
CaseSensitive: false,
|
||||
},
|
||||
expect: result{
|
||||
hasError: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
input: &models.HTTPAuthProxy{
|
||||
Endpoint: "https://127.0.0.1/login",
|
||||
TokenReviewEndpoint: "https://127.0.0.1/tokenreview",
|
||||
VerifyCert: true,
|
||||
SkipSearch: false,
|
||||
ServerCertificate: "",
|
||||
CaseSensitive: false,
|
||||
},
|
||||
expect: result{
|
||||
hasError: false,
|
||||
insecure: false,
|
||||
nilRootCA: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
input: &models.HTTPAuthProxy{
|
||||
Endpoint: "https://127.0.0.1/login",
|
||||
TokenReviewEndpoint: "https://127.0.0.1/tokenreview",
|
||||
VerifyCert: true,
|
||||
SkipSearch: false,
|
||||
ServerCertificate: `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
`,
|
||||
CaseSensitive: false,
|
||||
},
|
||||
expect: result{
|
||||
hasError: false,
|
||||
insecure: false,
|
||||
nilRootCA: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
output, err := getTLSConfig(c.input)
|
||||
if c.expect.hasError {
|
||||
assert.NotNil(t, err)
|
||||
continue
|
||||
} else {
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
if output != nil {
|
||||
assert.Equal(t, c.expect.insecure, output.InsecureSkipVerify)
|
||||
assert.Equal(t, c.expect.nilRootCA, output.RootCAs == nil)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -475,6 +475,7 @@ func HTTPAuthProxySetting() (*models.HTTPAuthProxy, error) {
|
||||
TokenReviewEndpoint: cfgMgr.Get(common.HTTPAuthProxyTokenReviewEndpoint).GetString(),
|
||||
VerifyCert: cfgMgr.Get(common.HTTPAuthProxyVerifyCert).GetBool(),
|
||||
SkipSearch: cfgMgr.Get(common.HTTPAuthProxySkipSearch).GetBool(),
|
||||
ServerCertificate: cfgMgr.Get(common.HTTPAuthProxyServerCertificate).GetString(),
|
||||
CaseSensitive: cfgMgr.Get(common.HTTPAuthProxyCaseSensitive).GetBool(),
|
||||
}, nil
|
||||
}
|
||||
|
@ -216,11 +216,44 @@ func currPath() string {
|
||||
}
|
||||
|
||||
func TestHTTPAuthProxySetting(t *testing.T) {
|
||||
certificate := `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
m := map[string]interface{}{
|
||||
common.HTTPAuthProxySkipSearch: "true",
|
||||
common.HTTPAuthProxyVerifyCert: "true",
|
||||
common.HTTPAuthProxyCaseSensitive: "false",
|
||||
common.HTTPAuthProxyEndpoint: "https://auth.proxy/suffix",
|
||||
common.HTTPAuthProxyServerCertificate: certificate,
|
||||
}
|
||||
InitWithSettings(m)
|
||||
v, e := HTTPAuthProxySetting()
|
||||
@ -230,6 +263,7 @@ func TestHTTPAuthProxySetting(t *testing.T) {
|
||||
SkipSearch: true,
|
||||
VerifyCert: true,
|
||||
CaseSensitive: false,
|
||||
ServerCertificate: certificate,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,7 @@ func TokenReview(rawToken string, authProxyConfig *models.HTTPAuthProxy) (k8s_ap
|
||||
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||
},
|
||||
BearerToken: rawToken,
|
||||
TLSClientConfig: rest.TLSClientConfig{
|
||||
Insecure: !authProxyConfig.VerifyCert,
|
||||
},
|
||||
TLSClientConfig: getTLSConfig(authProxyConfig),
|
||||
}
|
||||
authClient, err := rest.RESTClientFor(authClientCfg)
|
||||
if err != nil {
|
||||
@ -68,6 +66,17 @@ func TokenReview(rawToken string, authProxyConfig *models.HTTPAuthProxy) (k8s_ap
|
||||
|
||||
}
|
||||
|
||||
func getTLSConfig(config *models.HTTPAuthProxy) rest.TLSClientConfig {
|
||||
if config.VerifyCert && len(config.ServerCertificate) > 0 {
|
||||
return rest.TLSClientConfig{
|
||||
CAData: []byte(config.ServerCertificate),
|
||||
}
|
||||
}
|
||||
return rest.TLSClientConfig{
|
||||
Insecure: !config.VerifyCert,
|
||||
}
|
||||
}
|
||||
|
||||
// UserFromReviewStatus transform a review status to a user model.
|
||||
// Group entries will be populated if needed.
|
||||
func UserFromReviewStatus(status k8s_api_v1beta1.TokenReviewStatus) (*models.User, error) {
|
||||
|
@ -3,8 +3,10 @@ package authproxy
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/dao/group"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/api/authentication/v1beta1"
|
||||
"k8s.io/client-go/rest"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
@ -85,3 +87,72 @@ func TestUserFromReviewStatus(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTLSConfig(t *testing.T) {
|
||||
certificate := `-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
cases := []struct {
|
||||
input *models.HTTPAuthProxy
|
||||
expect rest.TLSClientConfig
|
||||
}{
|
||||
{
|
||||
input: &models.HTTPAuthProxy{
|
||||
Endpoint: "https://127.0.0.1/login",
|
||||
TokenReviewEndpoint: "https://127.0.0.1/tokenreview",
|
||||
VerifyCert: false,
|
||||
SkipSearch: false,
|
||||
ServerCertificate: "",
|
||||
CaseSensitive: false,
|
||||
},
|
||||
expect: rest.TLSClientConfig{
|
||||
Insecure: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
input: &models.HTTPAuthProxy{
|
||||
Endpoint: "https://127.0.0.1/login",
|
||||
TokenReviewEndpoint: "https://127.0.0.1/tokenreview",
|
||||
VerifyCert: true,
|
||||
SkipSearch: false,
|
||||
ServerCertificate: certificate,
|
||||
},
|
||||
expect: rest.TLSClientConfig{
|
||||
Insecure: false,
|
||||
CAData: []byte(certificate),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
assert.Equal(t, c.expect, getTLSConfig(c.input))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user