| 251 | } |
| 252 | |
| 253 | func AuthHandler(handler http.Handler, rDB *raft.Service, accessTokens *accesstoken.CredentialStore, tlsConfig *tls.Config) http.Handler { |
| 254 | authorizer := authz.NewAuthorizer(rDB, GrantPrefix, policyByRoute) |
| 255 | |
| 256 | rootCAs := x509.NewCertPool() |
| 257 | if tlsConfig != nil { |
| 258 | x509Cert, err := x509.ParseCertificate(tlsConfig.Certificates[0].Certificate[0]) |
| 259 | if err != nil { |
| 260 | log.Fatalkv(context.Background(), log.KeyError, err) |
| 261 | } |
| 262 | |
| 263 | authorizer.GrantInternal(x509Cert.Subject) |
| 264 | rootCAs = tlsConfig.ClientCAs |
| 265 | } |
| 266 | |
| 267 | authenticator := authn.NewAPI(accessTokens, crosscoreRPCPrefix, rootCAs) |
| 268 | |
| 269 | return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { |
| 270 | // TODO(tessr): check that this path exists; return early if this path isn't legit |
| 271 | req, err := authenticator.Authenticate(req) |
| 272 | if err != nil { |
| 273 | errorFormatter.Write(req.Context(), rw, errNotAuthenticated) |
| 274 | return |
| 275 | } |
| 276 | |
| 277 | err = authorizer.Authorize(req) |
| 278 | if err != nil { |
| 279 | errorFormatter.Write(req.Context(), rw, err) |
| 280 | return |
| 281 | } |
| 282 | handler.ServeHTTP(rw, req) |
| 283 | }) |
| 284 | } |
| 285 | |
| 286 | // timeoutContextHandler propagates the timeout, if any, provided as a header |
| 287 | // in the http request. |