github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/pkg/authorization/middleware.go (about) 1 package authorization 2 3 import ( 4 "net/http" 5 "sync" 6 7 "github.com/Sirupsen/logrus" 8 "github.com/docker/docker/pkg/plugingetter" 9 "golang.org/x/net/context" 10 ) 11 12 // Middleware uses a list of plugins to 13 // handle authorization in the API requests. 14 type Middleware struct { 15 mu sync.Mutex 16 plugins []Plugin 17 } 18 19 // NewMiddleware creates a new Middleware 20 // with a slice of plugins names. 21 func NewMiddleware(names []string, pg plugingetter.PluginGetter) *Middleware { 22 SetPluginGetter(pg) 23 return &Middleware{ 24 plugins: newPlugins(names), 25 } 26 } 27 28 // GetAuthzPlugins gets authorization plugins 29 func (m *Middleware) GetAuthzPlugins() []Plugin { 30 m.mu.Lock() 31 defer m.mu.Unlock() 32 return m.plugins 33 } 34 35 // SetAuthzPlugins sets authorization plugins 36 func (m *Middleware) SetAuthzPlugins(plugins []Plugin) { 37 m.mu.Lock() 38 m.plugins = plugins 39 m.mu.Unlock() 40 } 41 42 // SetPlugins sets the plugin used for authorization 43 func (m *Middleware) SetPlugins(names []string) { 44 m.mu.Lock() 45 m.plugins = newPlugins(names) 46 m.mu.Unlock() 47 } 48 49 // WrapHandler returns a new handler function wrapping the previous one in the request chain. 50 func (m *Middleware) WrapHandler(handler func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error) func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 51 return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 52 plugins := m.GetAuthzPlugins() 53 if len(plugins) == 0 { 54 return handler(ctx, w, r, vars) 55 } 56 57 user := "" 58 userAuthNMethod := "" 59 60 // Default authorization using existing TLS connection credentials 61 // FIXME: Non trivial authorization mechanisms (such as advanced certificate validations, kerberos support 62 // and ldap) will be extracted using AuthN feature, which is tracked under: 63 // https://github.com/docker/docker/pull/20883 64 if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 { 65 user = r.TLS.PeerCertificates[0].Subject.CommonName 66 userAuthNMethod = "TLS" 67 } 68 69 authCtx := NewCtx(plugins, user, userAuthNMethod, r.Method, r.RequestURI) 70 71 if err := authCtx.AuthZRequest(w, r); err != nil { 72 logrus.Errorf("AuthZRequest for %s %s returned error: %s", r.Method, r.RequestURI, err) 73 return err 74 } 75 76 rw := NewResponseModifier(w) 77 78 var errD error 79 80 if errD = handler(ctx, rw, r, vars); errD != nil { 81 logrus.Errorf("Handler for %s %s returned error: %s", r.Method, r.RequestURI, errD) 82 } 83 84 // There's a chance that the authCtx.plugins was updated. One of the reasons 85 // this can happen is when an authzplugin is disabled. 86 plugins = m.GetAuthzPlugins() 87 if len(plugins) == 0 { 88 logrus.Debug("There are no authz plugins in the chain") 89 return nil 90 } 91 92 authCtx.plugins = plugins 93 94 if err := authCtx.AuthZResponse(rw, r); errD == nil && err != nil { 95 logrus.Errorf("AuthZResponse for %s %s returned error: %s", r.Method, r.RequestURI, err) 96 return err 97 } 98 99 if errD != nil { 100 return errD 101 } 102 103 return nil 104 } 105 }