mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
improve the forbidden message
This commit is contained in:
parent
9705bb728e
commit
f6829bbde7
@ -308,7 +308,8 @@ func NewGenericServerResponse(code int, verb string, qualifiedResource schema.Gr
|
||||
message = "the server has asked for the client to provide credentials"
|
||||
case http.StatusForbidden:
|
||||
reason = metav1.StatusReasonForbidden
|
||||
message = "the server does not allow access to the requested resource"
|
||||
// the server message has details about who is trying to perform what action. Keep its message.
|
||||
message = serverMessage
|
||||
case http.StatusMethodNotAllowed:
|
||||
reason = metav1.StatusReasonMethodNotAllowed
|
||||
message = "the server does not allow this method on the requested resource"
|
||||
|
@ -40,12 +40,12 @@ func WithAuthorization(handler http.Handler, requestContextMapper api.RequestCon
|
||||
return
|
||||
}
|
||||
|
||||
attrs, err := GetAuthorizerAttributes(ctx)
|
||||
attributes, err := GetAuthorizerAttributes(ctx)
|
||||
if err != nil {
|
||||
internalError(w, req, err)
|
||||
return
|
||||
}
|
||||
authorized, reason, err := a.Authorize(attrs)
|
||||
authorized, reason, err := a.Authorize(attributes)
|
||||
if authorized {
|
||||
handler.ServeHTTP(w, req)
|
||||
return
|
||||
@ -55,8 +55,8 @@ func WithAuthorization(handler http.Handler, requestContextMapper api.RequestCon
|
||||
return
|
||||
}
|
||||
|
||||
glog.V(4).Infof("Forbidden: %#v, Reason: %s", req.RequestURI, reason)
|
||||
forbidden(w, req)
|
||||
glog.V(4).Infof("Forbidden: %#v, Reason: %q", req.RequestURI, reason)
|
||||
forbidden(attributes, w, req, reason)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/kubernetes/pkg/auth/authorizer"
|
||||
"k8s.io/kubernetes/pkg/util/runtime"
|
||||
)
|
||||
|
||||
@ -30,9 +31,28 @@ func badGatewayError(w http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
|
||||
// forbidden renders a simple forbidden error
|
||||
func forbidden(w http.ResponseWriter, req *http.Request) {
|
||||
func forbidden(attributes authorizer.Attributes, w http.ResponseWriter, req *http.Request, reason string) {
|
||||
msg := forbiddenMessage(attributes)
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
fmt.Fprintf(w, "Forbidden: %#v", req.RequestURI)
|
||||
fmt.Fprintf(w, "%s: %q", msg, reason)
|
||||
}
|
||||
|
||||
func forbiddenMessage(attributes authorizer.Attributes) string {
|
||||
username := ""
|
||||
if user := attributes.GetUser(); user != nil {
|
||||
username = user.GetName()
|
||||
}
|
||||
|
||||
resource := attributes.GetResource()
|
||||
if group := attributes.GetAPIGroup(); len(group) > 0 {
|
||||
resource = resource + "." + group
|
||||
}
|
||||
|
||||
if ns := attributes.GetNamespace(); len(ns) > 0 {
|
||||
return fmt.Sprintf("User %q cannot %s %s in the namespace %q.", username, attributes.GetVerb(), resource, ns)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("User %q cannot %s %s at the cluster scope.", username, attributes.GetVerb(), resource)
|
||||
}
|
||||
|
||||
// internalError renders a simple internal error
|
||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||
package filters
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
@ -37,7 +38,7 @@ func WithImpersonation(handler http.Handler, requestContextMapper api.RequestCon
|
||||
impersonationRequests, err := buildImpersonationRequests(req.Header)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("%v", err)
|
||||
forbidden(w, req)
|
||||
internalError(w, req, err)
|
||||
return
|
||||
}
|
||||
if len(impersonationRequests) == 0 {
|
||||
@ -47,12 +48,12 @@ func WithImpersonation(handler http.Handler, requestContextMapper api.RequestCon
|
||||
|
||||
ctx, exists := requestContextMapper.Get(req)
|
||||
if !exists {
|
||||
forbidden(w, req)
|
||||
internalError(w, req, errors.New("no context found for request"))
|
||||
return
|
||||
}
|
||||
requestor, exists := api.UserFrom(ctx)
|
||||
if !exists {
|
||||
forbidden(w, req)
|
||||
internalError(w, req, errors.New("no user found for request"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -100,15 +101,15 @@ func WithImpersonation(handler http.Handler, requestContextMapper api.RequestCon
|
||||
userExtra[extraKey] = append(userExtra[extraKey], extraValue)
|
||||
|
||||
default:
|
||||
glog.V(4).Infof("unknown impersonation request type: %v\n", impersonationRequest)
|
||||
forbidden(w, req)
|
||||
glog.V(4).Infof("unknown impersonation request type: %v", impersonationRequest)
|
||||
forbidden(actingAsAttributes, w, req, fmt.Sprintf("unknown impersonation request type: %v", impersonationRequest))
|
||||
return
|
||||
}
|
||||
|
||||
allowed, reason, err := a.Authorize(actingAsAttributes)
|
||||
if err != nil || !allowed {
|
||||
glog.V(4).Infof("Forbidden: %#v, Reason: %s, Error: %v", req.RequestURI, reason, err)
|
||||
forbidden(w, req)
|
||||
forbidden(actingAsAttributes, w, req, reason)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ func TestImpersonationFilter(t *testing.T) {
|
||||
expectedUser: &user.DefaultInfo{
|
||||
Name: "tester",
|
||||
},
|
||||
expectedCode: http.StatusForbidden,
|
||||
expectedCode: http.StatusInternalServerError,
|
||||
},
|
||||
{
|
||||
name: "impersonating-extra-without-user",
|
||||
@ -129,7 +129,7 @@ func TestImpersonationFilter(t *testing.T) {
|
||||
expectedUser: &user.DefaultInfo{
|
||||
Name: "tester",
|
||||
},
|
||||
expectedCode: http.StatusForbidden,
|
||||
expectedCode: http.StatusInternalServerError,
|
||||
},
|
||||
{
|
||||
name: "disallowed-group",
|
||||
|
Loading…
Reference in New Issue
Block a user