Skip to content

Feature request: Add Support for RFC 9126: Pushed Authorization Requests (PAR) #653

Open
@theadell

Description

@theadell

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)
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions