Description
I would like to propose adding support for the Pushed Authorization Requests (PAR)
Adding support for PAR improves security by sending the authorization request via the back channel (HTTPS) rather than the front channel (browser redirects). This minimizes the exposure of sensitive data and reduces the possibility of Man-In-The-Middle (MITM) attacks.
Moreover, with PAR, the authorization request may be authenticated, meaning that only legitimate clients can initiate the OAuth flow. This strengthens security by ensuring that only clients with the appropriate credentials can make authorization requests.
This feature is also particularly useful when used in conjunction with JWT Secured Authorization Request (RFC 9101), making the handling of more complex requests more efficient.
To implement RFC 9126 I propose extending the Endpoint
struct to include an PARURL
field:
type Endpoint struct {
AuthURL string
TokenURL string
PARURL string
// AuthStyle optionally specifies how the endpoint wants the
// client ID & client secret sent. The zero value means to auto-detect.
AuthStyle AuthStyle
}
A new method PushAuthRequest
is added to the Config
struct
func (c *Config) PushAuthRequest(ctx context.Context, state string, opts ...AuthCodeOption) (string, error)
This RequestPAR method would be responsible for creating a Pushed Authorization Request (PAR) by sending an HTTP POST request to the authorization server with the necessary parameters. Essentially it takes any parameter that can be passed to AuthCodeURL
It returns a URL to OAuth 2.0 provider's consent page which contains a reference to the authorization request made.
https://server.example.com/authorize?client_id=1234&request_uri=urn%3Aietf%3Aparams%3Aoauth%3Arequest_uri%3Aos6m1c9
An Example usage
func RequestEmailAccessHandler(config *oauth2.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
verifier, state := oauth2.GenerateVerifier(), oauth2.GenerateVerifier()
// store verifier in session ...
authzURL, err := config.PushAuthRequest(context.TODO(), state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(verifier))
if err != nil {
// handle error
}
http.Redirect(w, r, authzURL, http.StatusSeeOther)
}
}