From 2d14a0f589603fe476a6690e4295670e7f806f84 Mon Sep 17 00:00:00 2001 From: hongming Date: Fri, 25 Oct 2019 18:13:54 +0800 Subject: [PATCH] improve path exclusion rule Signed-off-by: hongming --- .../caddy-plugin/authenticate/authenticate.go | 7 ++-- .../caddy-plugin/authenticate/auto_load.go | 20 ++++++------ .../authentication/authentication.go | 11 ++++--- .../caddy-plugin/authentication/auto_load.go | 23 ++++++------- .../caddy-plugin/internal/exclusion_rule.go | 32 +++++++++++++++++++ 5 files changed, 65 insertions(+), 28 deletions(-) create mode 100644 pkg/apigateway/caddy-plugin/internal/exclusion_rule.go diff --git a/pkg/apigateway/caddy-plugin/authenticate/authenticate.go b/pkg/apigateway/caddy-plugin/authenticate/authenticate.go index f1c59ece2..6cb0aaff8 100644 --- a/pkg/apigateway/caddy-plugin/authenticate/authenticate.go +++ b/pkg/apigateway/caddy-plugin/authenticate/authenticate.go @@ -24,6 +24,7 @@ import ( "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/klog" + "kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal" "kubesphere.io/kubesphere/pkg/simple/client/redis" "log" "net/http" @@ -46,7 +47,7 @@ type Rule struct { RedisOptions *redis.RedisOptions TokenIdleTimeout time.Duration RedisClient *redis.RedisClient - ExceptedPath []string + ExclusionRules []internal.ExclusionRule } type User struct { @@ -61,8 +62,8 @@ var requestInfoFactory = request.RequestInfoFactory{ GrouplessAPIPrefixes: sets.NewString("api")} func (h Auth) ServeHTTP(resp http.ResponseWriter, req *http.Request) (int, error) { - for _, path := range h.Rule.ExceptedPath { - if httpserver.Path(req.URL.Path).Matches(path) { + for _, rule := range h.Rule.ExclusionRules { + if httpserver.Path(req.URL.Path).Matches(rule.Path) && (rule.Method == internal.AllMethod || req.Method == rule.Method) { return h.Next.ServeHTTP(resp, req) } } diff --git a/pkg/apigateway/caddy-plugin/authenticate/auto_load.go b/pkg/apigateway/caddy-plugin/authenticate/auto_load.go index 529b3c7cf..58ba4b485 100644 --- a/pkg/apigateway/caddy-plugin/authenticate/auto_load.go +++ b/pkg/apigateway/caddy-plugin/authenticate/auto_load.go @@ -19,9 +19,9 @@ package authenticate import ( "fmt" + "kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal" "kubesphere.io/kubesphere/pkg/simple/client/redis" - - "strings" + "kubesphere.io/kubesphere/pkg/utils/sliceutil" "time" "github.com/mholt/caddy" @@ -59,8 +59,8 @@ func Setup(c *caddy.Controller) error { func parse(c *caddy.Controller) (*Rule, error) { - rule := &Rule{ExceptedPath: make([]string, 0)} - + rule := &Rule{} + rule.ExclusionRules = make([]internal.ExclusionRule, 0) if c.Next() { args := c.RemainingArgs() switch len(args) { @@ -118,18 +118,20 @@ func parse(c *caddy.Controller) (*Rule, error) { return nil, c.ArgErr() } case "except": + if !c.NextArg() { return nil, c.ArgErr() } - rule.ExceptedPath = strings.Split(c.Val(), ",") + method := c.Val() - for i := 0; i < len(rule.ExceptedPath); i++ { - rule.ExceptedPath[i] = strings.TrimSpace(rule.ExceptedPath[i]) + if !sliceutil.HasString(internal.HttpMethods, method) { + return nil, c.ArgErr() } - if c.NextArg() { - return nil, c.ArgErr() + for c.NextArg() { + path := c.Val() + rule.ExclusionRules = append(rule.ExclusionRules, internal.ExclusionRule{Method: method, Path: path}) } } } diff --git a/pkg/apigateway/caddy-plugin/authentication/authentication.go b/pkg/apigateway/caddy-plugin/authentication/authentication.go index 6b2799200..d2e7a621d 100644 --- a/pkg/apigateway/caddy-plugin/authentication/authentication.go +++ b/pkg/apigateway/caddy-plugin/authentication/authentication.go @@ -23,6 +23,7 @@ import ( "fmt" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/endpoints/request" + "kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal" "kubesphere.io/kubesphere/pkg/utils/k8sutil" "log" "net/http" @@ -38,21 +39,21 @@ import ( ) type Authentication struct { - Rule Rule + Rule *Rule Next httpserver.Handler } type Rule struct { - Path string - ExceptedPath []string + Path string + ExclusionRules []internal.ExclusionRule } func (c Authentication) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { if httpserver.Path(r.URL.Path).Matches(c.Rule.Path) { - for _, path := range c.Rule.ExceptedPath { - if httpserver.Path(r.URL.Path).Matches(path) { + for _, rule := range c.Rule.ExclusionRules { + if httpserver.Path(r.URL.Path).Matches(rule.Path) && (rule.Method == internal.AllMethod || r.Method == rule.Method) { return c.Next.ServeHTTP(w, r) } } diff --git a/pkg/apigateway/caddy-plugin/authentication/auto_load.go b/pkg/apigateway/caddy-plugin/authentication/auto_load.go index c015aa00f..ee94d9eaf 100644 --- a/pkg/apigateway/caddy-plugin/authentication/auto_load.go +++ b/pkg/apigateway/caddy-plugin/authentication/auto_load.go @@ -19,10 +19,10 @@ package authentication import ( "fmt" - "strings" - "github.com/mholt/caddy" "github.com/mholt/caddy/caddyhttp/httpserver" + "kubesphere.io/kubesphere/pkg/apigateway/caddy-plugin/internal" + "kubesphere.io/kubesphere/pkg/utils/sliceutil" "kubesphere.io/kubesphere/pkg/informers" ) @@ -59,10 +59,10 @@ func Setup(c *caddy.Controller) error { return nil } -func parse(c *caddy.Controller) (Rule, error) { - - rule := Rule{ExceptedPath: make([]string, 0)} +func parse(c *caddy.Controller) (*Rule, error) { + rule := &Rule{} + rule.ExclusionRules = make([]internal.ExclusionRule, 0) if c.Next() { args := c.RemainingArgs() switch len(args) { @@ -83,17 +83,18 @@ func parse(c *caddy.Controller) (Rule, error) { break case "except": if !c.NextArg() { - return rule, c.ArgErr() + return nil, c.ArgErr() } - rule.ExceptedPath = strings.Split(c.Val(), ",") + method := c.Val() - for i := 0; i < len(rule.ExceptedPath); i++ { - rule.ExceptedPath[i] = strings.TrimSpace(rule.ExceptedPath[i]) + if !sliceutil.HasString(internal.HttpMethods, method) { + return nil, c.ArgErr() } - if c.NextArg() { - return rule, c.ArgErr() + for c.NextArg() { + path := c.Val() + rule.ExclusionRules = append(rule.ExclusionRules, internal.ExclusionRule{Method: method, Path: path}) } break } diff --git a/pkg/apigateway/caddy-plugin/internal/exclusion_rule.go b/pkg/apigateway/caddy-plugin/internal/exclusion_rule.go new file mode 100644 index 000000000..3b6054b3d --- /dev/null +++ b/pkg/apigateway/caddy-plugin/internal/exclusion_rule.go @@ -0,0 +1,32 @@ +/* + * + * Copyright 2019 The KubeSphere Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * / + */ + +package internal + +import "net/http" + +const AllMethod = "*" + +var HttpMethods = []string{AllMethod, http.MethodPost, http.MethodDelete, + http.MethodPatch, http.MethodPut, http.MethodGet, http.MethodOptions, http.MethodConnect} + +// Path exclusion rule +type ExclusionRule struct { + Method string + Path string +}