func (a *Authenticate) OAuthCallback(w http.ResponseWriter, r *http.Request) error {
	redirect, err := a.getOAuthCallback(w, r)
	if err != nil {
		return fmt.Errorf("authenticate.OAuthCallback: %w", err)
	}
	httputil.Redirect(w, r, redirect.String(), http.StatusFound)
	return nil
}
OAuthCallback handles the callback from the identity provider.

https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowSteps
https://openid.net/specs/openid-connect-core-1_0.html#AuthResponse
package authenticate
import (
	"context"
	"encoding/base64"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"time"
	"github.com/go-jose/go-jose/v3/jwt"
	"github.com/google/uuid"
	"github.com/gorilla/mux"
	"github.com/pomerium/csrf"
	"github.com/rs/cors"
	"golang.org/x/oauth2"
	"google.golang.org/protobuf/types/known/timestamppb"
	"github.com/pomerium/pomerium/authenticate/handlers/webauthn"
	"github.com/pomerium/pomerium/internal/httputil"
	"github.com/pomerium/pomerium/internal/identity"
	"github.com/pomerium/pomerium/internal/identity/manager"
	"github.com/pomerium/pomerium/internal/identity/oidc"
	"github.com/pomerium/pomerium/internal/log"
	"github.com/pomerium/pomerium/internal/middleware"
	"github.com/pomerium/pomerium/internal/sessions"
	"github.com/pomerium/pomerium/internal/telemetry/trace"
	"github.com/pomerium/pomerium/internal/urlutil"
	"github.com/pomerium/pomerium/pkg/cryptutil"
	"github.com/pomerium/pomerium/pkg/grpc/device"
	"github.com/pomerium/pomerium/pkg/grpc/directory"
	"github.com/pomerium/pomerium/pkg/grpc/session"
	"github.com/pomerium/pomerium/pkg/grpc/user"
)
func (a *Authenticate) Handler() http.Handler {
	r := httputil.NewRouter()
	a.Mount(r)
	return r
}
func (a *Authenticate) Mount(r *mux.Router) {
	r.StrictSlash(true)
	r.Use(middleware.SetHeaders(httputil.HeadersContentSecurityPolicy))
	r.Use(func(h http.Handler) http.Handler {
		options := a.options.Load()
		state := a.state.Load()
		csrfKey := fmt.Sprintf("%s_csrf", options.CookieName)
		return csrf.Protect(
			state.cookieSecret,
			csrf.Secure(options.CookieSecure),
			csrf.Path("/"),
			csrf.UnsafePaths(
				[]string{
					"/oauth2/callback",     
					"/.pomerium/sign_out",  
				}),
			csrf.FormValueName("state"),  
			csrf.CookieName(csrfKey),
			csrf.FieldName(csrfKey),
			csrf.SameSite(csrf.SameSiteLaxMode),
			csrf.ErrorHandler(httputil.HandlerFunc(httputil.CSRFFailureHandler)),
		)(h)
	})
	r.Path("/robots.txt").HandlerFunc(a.RobotsTxt).Methods(http.MethodGet)
	r.Path("/oauth2/callback").Handler(httputil.HandlerFunc(a.OAuthCallback)).Methods(http.MethodGet)
	a.mountDashboard(r)
	a.mountWellKnown(r)
}
func (a *Authenticate) mountDashboard(r *mux.Router) {
	sr := r.PathPrefix("/.pomerium").Subrouter()
	c := cors.New(cors.Options{
		AllowOriginRequestFunc: func(r *http.Request, _ string) bool {
			state := a.state.Load()
			err := middleware.ValidateRequestURL(r, state.sharedKey)
			if err != nil {
				log.FromRequest(r).Info().Err(err).Msg("authenticate: origin blocked")
			}
			return err == nil
		},
		AllowCredentials: true,
		AllowedHeaders:   []string{"*"},
	})
	sr.Use(c.Handler)
	sr.Use(a.RetrieveSession)
	sr.Use(a.VerifySession)
	sr.Path("/").Handler(a.requireValidSignatureOnRedirect(a.userInfo))
	sr.Path("/sign_in").Handler(a.requireValidSignature(a.SignIn))
	sr.Path("/sign_out").Handler(a.requireValidSignature(a.SignOut))
	sr.Path("/webauthn").Handler(webauthn.New(a.getWebauthnState))
}
func (a *Authenticate) mountWellKnown(r *mux.Router) {
	wk := r.PathPrefix("/.well-known/pomerium").Subrouter()
	wk.Path("/jwks.json").Handler(httputil.HandlerFunc(a.jwks)).Methods(http.MethodGet)
	wk.Path("/").Handler(httputil.HandlerFunc(a.wellKnown)).Methods(http.MethodGet)
}
func (a *Authenticate) wellKnown(w http.ResponseWriter, r *http.Request) error {
	state := a.state.Load()
	wellKnownURLS := struct {
		OAuth2Callback        string `json:"authentication_callback_endpoint"`  
		JSONWebKeySetURL      string `json:"jwks_uri"`                          
		FrontchannelLogoutURI string `json:"frontchannel_logout_uri"`           
	}{
		state.redirectURL.ResolveReference(&url.URL{Path: "/oauth2/callback"}).String(),
		state.redirectURL.ResolveReference(&url.URL{Path: "/.well-known/pomerium/jwks.json"}).String(),
		state.redirectURL.ResolveReference(&url.URL{Path: "/.pomerium/sign_out"}).String(),
	}
	w.Header().Set("X-CSRF-Token", csrf.Token(r))
	httputil.RenderJSON(w, http.StatusOK, wellKnownURLS)
	return nil
}
func (a *Authenticate) jwks(w http.ResponseWriter, r *http.Request) error {
	httputil.RenderJSON(w, http.StatusOK, a.state.Load().jwk)
	return nil
}
func (a *Authenticate) RetrieveSession(next http.Handler) http.Handler {
	return sessions.RetrieveSession(a.state.Load().sessionLoaders...)(next)
}
func (a *Authenticate) VerifySession(next http.Handler) http.Handler {
	return httputil.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
		ctx, span := trace.StartSpan(r.Context(), "authenticate.VerifySession")
		defer span.End()
		state := a.state.Load()
		sessionState, err := a.getSessionFromCtx(ctx)
		if err != nil {
			log.FromRequest(r).Info().Err(err).Msg("authenticate: session load error")
			return a.reauthenticateOrFail(w, r, err)
		}
		if state.dataBrokerClient == nil {
			return errors.New("authenticate: databroker client cannot be nil")
		}
		if _, err = session.Get(ctx, state.dataBrokerClient, sessionState.ID); err != nil {
			log.FromRequest(r).Info().Err(err).Str("id", sessionState.ID).Msg("authenticate: session not found in databroker")
			return a.reauthenticateOrFail(w, r, err)
		}
		next.ServeHTTP(w, r.WithContext(ctx))
		return nil
	})
}
func (a *Authenticate) RobotsTxt(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, "User-agent: *\nDisallow: /")
}
func (a *Authenticate) SignIn(w http.ResponseWriter, r *http.Request) error {
	ctx, span := trace.StartSpan(r.Context(), "authenticate.SignIn")
	defer span.End()
	state := a.state.Load()
	redirectURL, err := urlutil.ParseAndValidateURL(r.FormValue(urlutil.QueryRedirectURI))
	if err != nil {
		return httputil.NewError(http.StatusBadRequest, err)
	}
	jwtAudience := []string{state.redirectURL.Host, redirectURL.Host}
	if callbackStr := r.FormValue(urlutil.QueryCallbackURI); callbackStr != "" {
		callbackURL, err := urlutil.ParseAndValidateURL(callbackStr)
		if err != nil {
			return httputil.NewError(http.StatusBadRequest, err)
		}
		jwtAudience = append(jwtAudience, callbackURL.Host)
	}
	if fwdAuth := r.FormValue(urlutil.QueryForwardAuth); fwdAuth != "" {
		jwtAudience = append(jwtAudience, fwdAuth)
	}
	s, err := a.getSessionFromCtx(ctx)
	if err != nil {
		state.sessionStore.ClearSession(w, r)
		return err
	}
	newSession := sessions.NewSession(s, state.redirectURL.Host, jwtAudience)
	if err := state.sessionStore.SaveSession(w, r, s); err != nil {
		return httputil.NewError(http.StatusBadRequest, err)
	}
	if r.FormValue(urlutil.QueryIsProgrammatic) == "true" {
		newSession.Programmatic = true
	}
	signedJWT, err := state.sharedEncoder.Marshal(newSession)
	if err != nil {
		return httputil.NewError(http.StatusBadRequest, err)
	}
	encryptedJWT := cryptutil.Encrypt(a.state.Load().sharedCipher, signedJWT, nil)
	encodedJWT := base64.URLEncoding.EncodeToString(encryptedJWT)
	callbackURL, err := urlutil.GetCallbackURL(r, encodedJWT)
	if err != nil {
		return httputil.NewError(http.StatusBadRequest, err)
	}
	uri := urlutil.NewSignedURL(state.sharedKey, callbackURL)
	httputil.Redirect(w, r, uri.String(), http.StatusFound)
	return nil
}
func (a *Authenticate) SignOut(w http.ResponseWriter, r *http.Request) error {
	ctx, span := trace.StartSpan(r.Context(), "authenticate.SignOut")
	defer span.End()
	rawIDToken := a.revokeSession(ctx, w, r)
	redirectString := ""
	signOutURL, err := a.options.Load().GetSignOutRedirectURL()
	if err != nil {
		return err
	}
	if signOutURL != nil {
		redirectString = signOutURL.String()
	}
	if uri := r.FormValue(urlutil.QueryRedirectURI); uri != "" {
		redirectString = uri
	}
	endSessionURL, err := a.provider.Load().LogOut()
	if err == nil && redirectString != "" {
		params := url.Values{}
		params.Add("id_token_hint", rawIDToken)
		params.Add("post_logout_redirect_uri", redirectString)
		endSessionURL.RawQuery = params.Encode()
		redirectString = endSessionURL.String()
	} else if !errors.Is(err, oidc.ErrSignoutNotImplemented) {
		log.Warn(r.Context()).Err(err).Msg("authenticate.SignOut: failed getting session")
	}
	if redirectString != "" {
		httputil.Redirect(w, r, redirectString, http.StatusFound)
		return nil
	}
	return httputil.NewError(http.StatusOK, errors.New("user logged out"))
}
func (a *Authenticate) reauthenticateOrFail(w http.ResponseWriter, r *http.Request, err error) error {
	state := a.state.Load()
	if reqType := r.Header.Get("X-Requested-With"); strings.EqualFold(reqType, "XmlHttpRequest") {
		return httputil.NewError(http.StatusUnauthorized, err)
	}
	state.sessionStore.ClearSession(w, r)
	redirectURL := state.redirectURL.ResolveReference(r.URL)
	nonce := csrf.Token(r)
	now := time.Now().Unix()
	b := []byte(fmt.Sprintf("%s|%d|", nonce, now))
	enc := cryptutil.Encrypt(state.cookieCipher, []byte(redirectURL.String()), b)
	b = append(b, enc...)
	encodedState := base64.URLEncoding.EncodeToString(b)
	signinURL, err := a.provider.Load().GetSignInURL(encodedState)
	if err != nil {
		return httputil.NewError(http.StatusInternalServerError,
			fmt.Errorf("failed to get sign in url: %w", err))
	}
	httputil.Redirect(w, r, signinURL, http.StatusFound)
	return nil
}