| 319 | } |
| 320 | |
| 321 | func (h *AuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
| 322 | // Retrieve saved session. |
| 323 | cookie, err := r.Cookie(authCookieName) |
| 324 | if err != nil { |
| 325 | echo(Log{"t": "oauth2_cookie", "error": err.Error()}) |
| 326 | http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) |
| 327 | return |
| 328 | } |
| 329 | |
| 330 | sessionID := cookie.Value |
| 331 | session, ok := h.auth.get(sessionID) |
| 332 | if !ok { |
| 333 | echo(Log{"t": "oauth2_session", "error": "not found"}) |
| 334 | http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) |
| 335 | return |
| 336 | } |
| 337 | |
| 338 | // Handle errors from provider. |
| 339 | if err := r.URL.Query().Get("error"); err != "" { |
| 340 | errorDescription := r.URL.Query().Get("error_description") |
| 341 | echo(Log{"t": "oauth2_callback", "error": err, "description": errorDescription}) |
| 342 | http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) |
| 343 | return |
| 344 | } |
| 345 | |
| 346 | // Compare to stored state. |
| 347 | responseState := r.URL.Query().Get("state") |
| 348 | if session.state != responseState { |
| 349 | echo(Log{"t": "oauth2_state", "error": "failed matching state"}) |
| 350 | http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) |
| 351 | return |
| 352 | } |
| 353 | |
| 354 | oAuth2Provider, err := oidc.NewProvider(r.Context(), h.auth.conf.ProviderURL) |
| 355 | if err != nil { |
| 356 | echo(Log{"t": "oauth2_oidc_provider", "error": err.Error()}) |
| 357 | http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) |
| 358 | return |
| 359 | } |
| 360 | |
| 361 | oauth2Token, err := h.auth.oauth.Exchange(r.Context(), r.URL.Query().Get("code")) |
| 362 | if err != nil { |
| 363 | echo(Log{"t": "oauth2_exchange", "error": err.Error()}) |
| 364 | http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) |
| 365 | return |
| 366 | } |
| 367 | |
| 368 | rawIDToken, ok := oauth2Token.Extra("id_token").(string) |
| 369 | if !ok { |
| 370 | echo(Log{"t": "oauth2_exchange", "error": "failed reading id_token"}) |
| 371 | http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) |
| 372 | return |
| 373 | } |
| 374 | |
| 375 | oidcVerifier := oAuth2Provider.Verifier(&oidc.Config{ClientID: h.auth.oauth.ClientID}) |
| 376 | idToken, err := oidcVerifier.Verify(r.Context(), rawIDToken) |
| 377 | if err != nil { |
| 378 | echo(Log{"t": "oauth2_oidc_verifier", "error": "failed verifying id_token"}) |