golang / golang/oauth2

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

Open
#653 3 comments 1 reaction 0 assignees View on GitHub
Dominant language
Go
Stars
5.9k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

I would like to propose adding support for the [Pushed Authorization Requests (PAR)](https://datatracker.ietf.org/doc/html/rfc9126)

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)](https://datatracker.ietf.org/doc/html/rfc9101), making the handling of more complex requests more efficient.

To implement RFC 9126 I propose extending the `Endpoint` struct to include an `PARURL` field:
```go
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
```go
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

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

Contributor guide

Open the contributing guide

Research direction

Start with the existing Endpoint and Config types and trace how AuthCodeURL assembles authorization parameters. Compare that flow with RFC 9126 to determine how PushAuthRequest should submit the request and produce the consent URL containing the request reference. Done means PAR is exposed through the proposed endpoint field and Config method while accepting the parameters supported by AuthCodeURL.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, authentication
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.