Auth Proxy: encoding of non-ASCII headers (#44797)
* Decode auth proxy headers using URL encoding * Header encoding configuration via settings file * Rename configuration setting to headers_encoded * Quoted-printable encoding * Tests for AuthProxy * Fix encoding name * Remove authproxy init
This commit is contained in:
@@ -84,14 +84,14 @@ type Options struct {
|
||||
|
||||
// New instance of the AuthProxy.
|
||||
func New(cfg *setting.Cfg, options *Options) *AuthProxy {
|
||||
header := options.Ctx.Req.Header.Get(cfg.AuthProxyHeaderName)
|
||||
return &AuthProxy{
|
||||
auth := &AuthProxy{
|
||||
remoteCache: options.RemoteCache,
|
||||
cfg: cfg,
|
||||
ctx: options.Ctx,
|
||||
orgID: options.OrgID,
|
||||
header: header,
|
||||
}
|
||||
auth.header = auth.getDecodedHeader(cfg.AuthProxyHeaderName)
|
||||
return auth
|
||||
}
|
||||
|
||||
// IsEnabled checks if the auth proxy is enabled.
|
||||
@@ -313,6 +313,17 @@ func (auth *AuthProxy) LoginViaHeader() (int64, error) {
|
||||
return upsert.Result.Id, nil
|
||||
}
|
||||
|
||||
// getDecodedHeader gets decoded value of a header with given headerName
|
||||
func (auth *AuthProxy) getDecodedHeader(headerName string) string {
|
||||
headerValue := auth.ctx.Req.Header.Get(headerName)
|
||||
|
||||
if auth.cfg.AuthProxyHeadersEncoded {
|
||||
headerValue = util.DecodeQuotedPrintable(headerValue)
|
||||
}
|
||||
|
||||
return headerValue
|
||||
}
|
||||
|
||||
// headersIterator iterates over all non-empty supported additional headers
|
||||
func (auth *AuthProxy) headersIterator(fn func(field string, header string)) {
|
||||
for _, field := range supportedHeaderFields {
|
||||
@@ -321,7 +332,7 @@ func (auth *AuthProxy) headersIterator(fn func(field string, header string)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if value := auth.ctx.Req.Header.Get(h); value != "" {
|
||||
if value := auth.getDecodedHeader(h); value != "" {
|
||||
fn(field, strings.TrimSpace(value))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,18 +21,19 @@ import (
|
||||
|
||||
const hdrName = "markelog"
|
||||
|
||||
func prepareMiddleware(t *testing.T, remoteCache *remotecache.RemoteCache, cb func(*http.Request, *setting.Cfg)) *AuthProxy {
|
||||
func prepareMiddleware(t *testing.T, remoteCache *remotecache.RemoteCache, configureReq func(*http.Request, *setting.Cfg)) *AuthProxy {
|
||||
t.Helper()
|
||||
|
||||
cfg := setting.NewCfg()
|
||||
cfg.AuthProxyHeaderName = "X-Killa"
|
||||
|
||||
req, err := http.NewRequest("POST", "http://example.com", nil)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set(cfg.AuthProxyHeaderName, hdrName)
|
||||
|
||||
if cb != nil {
|
||||
cb(req, cfg)
|
||||
cfg := setting.NewCfg()
|
||||
|
||||
if configureReq != nil {
|
||||
configureReq(req, cfg)
|
||||
} else {
|
||||
cfg.AuthProxyHeaderName = "X-Killa"
|
||||
req.Header.Set(cfg.AuthProxyHeaderName, hdrName)
|
||||
}
|
||||
|
||||
ctx := &models.ReqContext{
|
||||
@@ -84,9 +85,11 @@ func TestMiddlewareContext(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
auth := prepareMiddleware(t, cache, func(req *http.Request, cfg *setting.Cfg) {
|
||||
cfg.AuthProxyHeaderName = "X-Killa"
|
||||
cfg.AuthProxyHeaders = map[string]string{"Groups": "X-WEBAUTH-GROUPS", "Role": "X-WEBAUTH-ROLE"}
|
||||
req.Header.Set(cfg.AuthProxyHeaderName, hdrName)
|
||||
req.Header.Set("X-WEBAUTH-GROUPS", group)
|
||||
req.Header.Set("X-WEBAUTH-ROLE", role)
|
||||
cfg.AuthProxyHeaders = map[string]string{"Groups": "X-WEBAUTH-GROUPS", "Role": "X-WEBAUTH-ROLE"}
|
||||
})
|
||||
assert.Equal(t, "auth-proxy-sync-ttl:f5acfffd56daac98d502ef8c8b8c5d56", key)
|
||||
|
||||
@@ -191,3 +194,26 @@ func TestMiddlewareContext_ldap(t *testing.T) {
|
||||
assert.False(t, stub.LoginCalled)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDecodeHeader(t *testing.T) {
|
||||
cache := remotecache.NewFakeStore(t)
|
||||
t.Run("should not decode header if not enabled in settings", func(t *testing.T) {
|
||||
auth := prepareMiddleware(t, cache, func(req *http.Request, cfg *setting.Cfg) {
|
||||
cfg.AuthProxyHeaderName = "X-WEBAUTH-USER"
|
||||
cfg.AuthProxyHeadersEncoded = false
|
||||
req.Header.Set(cfg.AuthProxyHeaderName, "M=C3=BCnchen")
|
||||
})
|
||||
|
||||
assert.Equal(t, "M=C3=BCnchen", auth.header)
|
||||
})
|
||||
|
||||
t.Run("should decode header if enabled in settings", func(t *testing.T) {
|
||||
auth := prepareMiddleware(t, cache, func(req *http.Request, cfg *setting.Cfg) {
|
||||
cfg.AuthProxyHeaderName = "X-WEBAUTH-USER"
|
||||
cfg.AuthProxyHeadersEncoded = true
|
||||
req.Header.Set(cfg.AuthProxyHeaderName, "M=C3=BCnchen")
|
||||
})
|
||||
|
||||
assert.Equal(t, "München", auth.header)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user