Skip to content

Commit

Permalink
feat(api): skip auth on specific endpoints
Browse files Browse the repository at this point in the history
Signed-off-by: Jakub Dyszkiewicz <[email protected]>
  • Loading branch information
jakubdyszkiewicz committed Nov 27, 2023
1 parent 716aaf2 commit c17faff
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 28 deletions.
32 changes: 32 additions & 0 deletions pkg/api-server/authn/skip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package authn

import (
"strings"

"github.com/emicklei/go-restful/v3"
)

const (
MetadataAuthKey = "auth"
MetadataAuthSkip = "skip"
)

// UnauthorizedPathPrefixes is another way to add path prefixes as unauthorized endpoint.
// Prefer MetadataAuthKey, use UnauthorizedPathPrefixes if needed.
var UnauthorizedPathPrefixes = map[string]struct{}{
"/gui": {},
}

func SkipAuth(request *restful.Request) bool {
if route := request.SelectedRoute(); route != nil {
if route.Metadata()[MetadataAuthKey] == MetadataAuthSkip {
return true
}
}
for prefix := range UnauthorizedPathPrefixes {
if strings.HasPrefix(request.Request.RequestURI, prefix) {
return true
}
}
return false
}
59 changes: 31 additions & 28 deletions pkg/api-server/index_endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/emicklei/go-restful/v3"

"github.com/kumahq/kuma/pkg/api-server/authn"
"github.com/kumahq/kuma/pkg/api-server/types"
kuma_version "github.com/kumahq/kuma/pkg/version"
)
Expand All @@ -20,33 +21,35 @@ func addIndexWsEndpoints(ws *restful.WebService, getInstanceId func() string, ge
if err != nil {
return err
}
ws.Route(ws.GET("/").To(func(req *restful.Request, resp *restful.Response) {
if instanceId == "" {
instanceId = getInstanceId()
}

if clusterId == "" {
clusterId = getClusterId()
}

if !enableGUI {
guiURL = ""
}

response := types.IndexResponse{
Hostname: hostname,
Tagline: kuma_version.Product,
Product: kuma_version.Product,
Version: kuma_version.Build.Version,
BasedOnKuma: kuma_version.Build.BasedOnKuma,
InstanceId: instanceId,
ClusterId: clusterId,
GuiURL: guiURL,
}

if err := resp.WriteAsJson(response); err != nil {
log.Error(err, "Could not write the index response")
}
}))
ws.Route(ws.GET("/").
Metadata(authn.MetadataAuthKey, authn.MetadataAuthSkip).
To(func(req *restful.Request, resp *restful.Response) {
if instanceId == "" {
instanceId = getInstanceId()
}

if clusterId == "" {
clusterId = getClusterId()
}

if !enableGUI {
guiURL = ""
}

response := types.IndexResponse{
Hostname: hostname,
Tagline: kuma_version.Product,
Product: kuma_version.Product,
Version: kuma_version.Build.Version,
BasedOnKuma: kuma_version.Build.BasedOnKuma,
InstanceId: instanceId,
ClusterId: clusterId,
GuiURL: guiURL,
}

if err := resp.WriteAsJson(response); err != nil {
log.Error(err, "Could not write the index response")
}
}))
return nil
}
4 changes: 4 additions & 0 deletions pkg/plugins/authn/api-server/tokens/authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ var log = core.Log.WithName("plugins").WithName("authn").WithName("api-server").

func UserTokenAuthenticator(validator issuer.UserTokenValidator) authn.Authenticator {
return func(request *restful.Request, response *restful.Response, chain *restful.FilterChain) {
if authn.SkipAuth(request) {
chain.ProcessFilter(request, response)
return
}
authnHeader := request.Request.Header.Get("authorization")
if user.FromCtx(request.Request.Context()).Name == user.Anonymous.Name && // do not overwrite existing user
authnHeader != "" &&
Expand Down
21 changes: 21 additions & 0 deletions test/e2e_env/universal/auth/user_auth.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package auth

import (
"net/http"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

Expand Down Expand Up @@ -55,4 +57,23 @@ func UserAuth() {
Expect(kumactl.RunKumactl("get", "dataplanes")).To(Succeed())
Expect(kumactl.RunKumactl("get", "secrets")).ToNot(Succeed())
})

DescribeTable("should ignore auth data on unauthorized endpoints",
func(endpoint string) {
// given
req, err := http.NewRequest("GET", universal.Cluster.GetKuma().GetAPIServerAddress()+endpoint, nil)
Expect(err).ToNot(HaveOccurred())
req.Header.Add("authorization", "Bearer invliddata")

// when
resp, err := http.DefaultClient.Do(req)

// then
Expect(err).ToNot(HaveOccurred())
defer resp.Body.Close()
Expect(resp.StatusCode).To(Equal(200))
},
Entry("index", "/"),
Entry("gui", "/gui/"),
)
}

0 comments on commit c17faff

Please sign in to comment.