diff --git a/api/server/middleware/authorization.go b/api/server/middleware/authorization.go index cbfa99e7b3..0163d81fb8 100644 --- a/api/server/middleware/authorization.go +++ b/api/server/middleware/authorization.go @@ -13,11 +13,19 @@ import ( func NewAuthorizationMiddleware(plugins []authorization.Plugin) Middleware { return func(handler httputils.APIFunc) httputils.APIFunc { return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - // FIXME: fill when authN gets in - // User and UserAuthNMethod are taken from AuthN plugins - // Currently tracked in https://github.com/docker/docker/pull/13994 + user := "" userAuthNMethod := "" + + // Default authorization using existing TLS connection credentials + // FIXME: Non trivial authorization mechanisms (such as advanced certificate validations, kerberos support + // and ldap) will be extracted using AuthN feature, which is tracked under: + // https://github.com/docker/docker/pull/20883 + if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 { + user = r.TLS.PeerCertificates[0].Subject.CommonName + userAuthNMethod = "TLS" + } + authCtx := authorization.NewCtx(plugins, user, userAuthNMethod, r.Method, r.RequestURI) if err := authCtx.AuthZRequest(w, r); err != nil { diff --git a/integration-cli/docker_cli_authz_unix_test.go b/integration-cli/docker_cli_authz_unix_test.go index 0a208d75e1..6d58d6d3db 100644 --- a/integration-cli/docker_cli_authz_unix_test.go +++ b/integration-cli/docker_cli_authz_unix_test.go @@ -53,6 +53,8 @@ type authorizationController struct { psRequestCnt int // psRequestCnt counts the number of calls to list container request api psResponseCnt int // psResponseCnt counts the number of calls to list containers response API requestsURIs []string // requestsURIs stores all request URIs that are sent to the authorization controller + reqUser string + resUser string } func (s *DockerAuthzSuite) SetUpTest(c *check.C) { @@ -104,6 +106,7 @@ func (s *DockerAuthzSuite) SetUpSuite(c *check.C) { } b, err := json.Marshal(reqRes) c.Assert(err, check.IsNil) + s.ctrl.reqUser = authReq.User w.Write(b) }) @@ -131,6 +134,7 @@ func (s *DockerAuthzSuite) SetUpSuite(c *check.C) { } b, err := json.Marshal(resRes) c.Assert(err, check.IsNil) + s.ctrl.resUser = authReq.User w.Write(b) }) @@ -213,6 +217,45 @@ func (s *DockerAuthzSuite) TestAuthZPluginAllowRequest(c *check.C) { c.Assert(s.ctrl.psResponseCnt, check.Equals, 1) } +func (s *DockerAuthzSuite) TestAuthZPluginTls(c *check.C) { + + const testDaemonHTTPSAddr = "tcp://localhost:4271" + // start the daemon and load busybox, --net=none build fails otherwise + // cause it needs to pull busybox + if err := s.d.Start( + "--authorization-plugin="+testAuthZPlugin, + "--tlsverify", + "--tlscacert", + "fixtures/https/ca.pem", + "--tlscert", + "fixtures/https/server-cert.pem", + "--tlskey", + "fixtures/https/server-key.pem", + "-H", testDaemonHTTPSAddr); err != nil { + c.Fatalf("Could not start daemon with busybox: %v", err) + } + + s.ctrl.reqRes.Allow = true + s.ctrl.resRes.Allow = true + + out, _ := dockerCmd( + c, + "--tlsverify", + "--tlscacert", "fixtures/https/ca.pem", + "--tlscert", "fixtures/https/client-cert.pem", + "--tlskey", "fixtures/https/client-key.pem", + "-H", + testDaemonHTTPSAddr, + "version", + ) + if !strings.Contains(out, "Server") { + c.Fatalf("docker version should return information of server side") + } + + c.Assert(s.ctrl.reqUser, check.Equals, "client") + c.Assert(s.ctrl.resUser, check.Equals, "client") +} + func (s *DockerAuthzSuite) TestAuthZPluginDenyRequest(c *check.C) { err := s.d.Start("--authorization-plugin=" + testAuthZPlugin) c.Assert(err, check.IsNil)