mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 22:17:14 +00:00
Merge pull request #37697 from deads2k/auth-06-simplify-authz
Automatic merge from submit-queue (batch tested with PRs 35300, 36709, 37643, 37813, 37697) simplify the authorization attribute getter Construct the authorization attributes directly from the context. This eliminates unnecessary redirection. @sttts
This commit is contained in:
commit
332305cba9
@ -752,7 +752,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unrecognized action verb: %s", action.Verb)
|
return nil, fmt.Errorf("unrecognized action verb: %s", action.Verb)
|
||||||
}
|
}
|
||||||
// Note: update GetAttribs() when adding a custom handler.
|
// Note: update GetAuthorizerAttributes() when adding a custom handler.
|
||||||
}
|
}
|
||||||
return &apiResource, nil
|
return &apiResource, nil
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package filters
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@ -28,6 +29,7 @@ import (
|
|||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/pborman/uuid"
|
"github.com/pborman/uuid"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
authenticationapi "k8s.io/kubernetes/pkg/apis/authentication"
|
authenticationapi "k8s.io/kubernetes/pkg/apis/authentication"
|
||||||
utilnet "k8s.io/kubernetes/pkg/util/net"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
)
|
)
|
||||||
@ -86,12 +88,17 @@ var _ http.Hijacker = &fancyResponseWriterDelegator{}
|
|||||||
// 2. the response line containing:
|
// 2. the response line containing:
|
||||||
// - the unique id from 1
|
// - the unique id from 1
|
||||||
// - response code
|
// - response code
|
||||||
func WithAudit(handler http.Handler, attributeGetter RequestAttributeGetter, out io.Writer) http.Handler {
|
func WithAudit(handler http.Handler, requestContextMapper api.RequestContextMapper, out io.Writer) http.Handler {
|
||||||
if out == nil {
|
if out == nil {
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
attribs, err := attributeGetter.GetAttribs(req)
|
ctx, ok := requestContextMapper.Get(req)
|
||||||
|
if !ok {
|
||||||
|
internalError(w, req, errors.New("no context found for request"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
attribs, err := GetAuthorizerAttributes(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
internalError(w, req, err)
|
internalError(w, req, err)
|
||||||
return
|
return
|
||||||
|
@ -74,10 +74,9 @@ func (*fakeHTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
func TestAudit(t *testing.T) {
|
func TestAudit(t *testing.T) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
attributeGetter := NewRequestAttributeGetter(&fakeRequestContextMapper{
|
handler := WithAudit(&fakeHTTPHandler{}, &fakeRequestContextMapper{
|
||||||
user: &user.DefaultInfo{Name: "admin"},
|
user: &user.DefaultInfo{Name: "admin"},
|
||||||
})
|
}, &buf)
|
||||||
handler := WithAudit(&fakeHTTPHandler{}, attributeGetter, &buf)
|
|
||||||
|
|
||||||
req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil)
|
req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil)
|
||||||
req.RemoteAddr = "127.0.0.1"
|
req.RemoteAddr = "127.0.0.1"
|
||||||
|
@ -28,13 +28,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// WithAuthorizationCheck passes all authorized requests on to handler, and returns a forbidden error otherwise.
|
// WithAuthorizationCheck passes all authorized requests on to handler, and returns a forbidden error otherwise.
|
||||||
func WithAuthorization(handler http.Handler, getAttribs RequestAttributeGetter, a authorizer.Authorizer) http.Handler {
|
func WithAuthorization(handler http.Handler, requestContextMapper api.RequestContextMapper, a authorizer.Authorizer) http.Handler {
|
||||||
if a == nil {
|
if a == nil {
|
||||||
glog.Warningf("Authorization is disabled")
|
glog.Warningf("Authorization is disabled")
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
attrs, err := getAttribs.GetAttribs(req)
|
ctx, ok := requestContextMapper.Get(req)
|
||||||
|
if !ok {
|
||||||
|
internalError(w, req, errors.New("no context found for request"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
attrs, err := GetAuthorizerAttributes(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
internalError(w, req, err)
|
internalError(w, req, err)
|
||||||
return
|
return
|
||||||
@ -54,28 +60,9 @@ func WithAuthorization(handler http.Handler, getAttribs RequestAttributeGetter,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestAttributeGetter is a function that extracts authorizer.Attributes from an http.Request
|
func GetAuthorizerAttributes(ctx api.Context) (authorizer.Attributes, error) {
|
||||||
type RequestAttributeGetter interface {
|
|
||||||
GetAttribs(req *http.Request) (authorizer.Attributes, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type requestAttributeGetter struct {
|
|
||||||
requestContextMapper api.RequestContextMapper
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAttributeGetter returns an object which implements the RequestAttributeGetter interface.
|
|
||||||
func NewRequestAttributeGetter(requestContextMapper api.RequestContextMapper) RequestAttributeGetter {
|
|
||||||
return &requestAttributeGetter{requestContextMapper}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *requestAttributeGetter) GetAttribs(req *http.Request) (authorizer.Attributes, error) {
|
|
||||||
attribs := authorizer.AttributesRecord{}
|
attribs := authorizer.AttributesRecord{}
|
||||||
|
|
||||||
ctx, ok := r.requestContextMapper.Get(req)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("no context found for request")
|
|
||||||
}
|
|
||||||
|
|
||||||
user, ok := api.UserFrom(ctx)
|
user, ok := api.UserFrom(ctx)
|
||||||
if ok {
|
if ok {
|
||||||
attribs.User = user
|
attribs.User = user
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package filters
|
package filters
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -27,9 +28,8 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/auth/authorizer"
|
"k8s.io/kubernetes/pkg/auth/authorizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetAttribs(t *testing.T) {
|
func TestGetAuthorizerAttributes(t *testing.T) {
|
||||||
mapper := api.NewRequestContextMapper()
|
mapper := api.NewRequestContextMapper()
|
||||||
attributeGetter := NewRequestAttributeGetter(mapper)
|
|
||||||
|
|
||||||
testcases := map[string]struct {
|
testcases := map[string]struct {
|
||||||
Verb string
|
Verb string
|
||||||
@ -108,7 +108,12 @@ func TestGetAttribs(t *testing.T) {
|
|||||||
var attribs authorizer.Attributes
|
var attribs authorizer.Attributes
|
||||||
var err error
|
var err error
|
||||||
var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
attribs, err = attributeGetter.GetAttribs(req)
|
ctx, ok := mapper.Get(req)
|
||||||
|
if !ok {
|
||||||
|
internalError(w, req, errors.New("no context found for request"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
attribs, err = GetAuthorizerAttributes(ctx)
|
||||||
})
|
})
|
||||||
handler = WithRequestInfo(handler, newTestRequestInfoResolver(), mapper)
|
handler = WithRequestInfo(handler, newTestRequestInfoResolver(), mapper)
|
||||||
handler = api.WithRequestContext(handler, mapper)
|
handler = api.WithRequestContext(handler, mapper)
|
||||||
|
@ -485,8 +485,6 @@ func (c *Config) MaybeGenerateServingCerts(alternateIPs ...net.IP) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) (secure, insecure http.Handler) {
|
func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) (secure, insecure http.Handler) {
|
||||||
attributeGetter := apiserverfilters.NewRequestAttributeGetter(c.RequestContextMapper)
|
|
||||||
|
|
||||||
generic := func(handler http.Handler) http.Handler {
|
generic := func(handler http.Handler) http.Handler {
|
||||||
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
|
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
|
||||||
handler = genericfilters.WithPanicRecovery(handler, c.RequestContextMapper)
|
handler = genericfilters.WithPanicRecovery(handler, c.RequestContextMapper)
|
||||||
@ -497,10 +495,10 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) (secure, insec
|
|||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
audit := func(handler http.Handler) http.Handler {
|
audit := func(handler http.Handler) http.Handler {
|
||||||
return apiserverfilters.WithAudit(handler, attributeGetter, c.AuditWriter)
|
return apiserverfilters.WithAudit(handler, c.RequestContextMapper, c.AuditWriter)
|
||||||
}
|
}
|
||||||
protect := func(handler http.Handler) http.Handler {
|
protect := func(handler http.Handler) http.Handler {
|
||||||
handler = apiserverfilters.WithAuthorization(handler, attributeGetter, c.Authorizer)
|
handler = apiserverfilters.WithAuthorization(handler, c.RequestContextMapper, c.Authorizer)
|
||||||
handler = apiserverfilters.WithImpersonation(handler, c.RequestContextMapper, c.Authorizer)
|
handler = apiserverfilters.WithImpersonation(handler, c.RequestContextMapper, c.Authorizer)
|
||||||
handler = audit(handler) // before impersonation to read original user
|
handler = audit(handler) // before impersonation to read original user
|
||||||
handler = authhandlers.WithAuthentication(handler, c.RequestContextMapper, c.Authenticator, authhandlers.Unauthorized(c.SupportsBasicAuth))
|
handler = authhandlers.WithAuthentication(handler, c.RequestContextMapper, c.Authenticator, authhandlers.Unauthorized(c.SupportsBasicAuth))
|
||||||
|
Loading…
Reference in New Issue
Block a user