refactor: reuse generic OIDC provider logic in Apple provider
Address review feedback: - Wire OIDCOptions through NewOIDCProvider instead of constructing OIDCProvider manually - Default AuthRequestResponseMode to form_post instead of overriding GetLoginURL - Drop the ValidateSession override in favour of the generic OIDC one - Use options.AppleProvider constant in client secret validation - Regenerate alpha config docs (appleConfig, authStyle) - Fix CHANGELOG entry to reference #3293 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: LYJW131 <lyjw2007@gmail.com>
This commit is contained in:
parent
33252dd11c
commit
15dfd6e617
|
|
@ -312,6 +312,19 @@ They may change between releases without notice.
|
|||
| `metricsServer` | _[Server](#server)_ | MetricsServer is used to configure the HTTP(S) server for metrics.<br/>You may choose to run both HTTP and HTTPS servers simultaneously.<br/>This can be done by setting the BindAddress and the SecureBindAddress simultaneously.<br/>To use the secure server you must configure a TLS certificate and key. |
|
||||
| `providers` | _[Providers](#providers)_ | Providers is used to configure your provider. **Multiple-providers is not<br/>yet working.** [This feature is tracked in<br/>#925](https://github.com/oauth2-proxy/oauth2-proxy/issues/926) |
|
||||
|
||||
### AppleOptions
|
||||
|
||||
(**Appears on:** [Provider](#provider))
|
||||
|
||||
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `teamID` | _string_ | TeamID is the 10-character Apple Developer Team ID |
|
||||
| `keyID` | _string_ | KeyID is the 10-character identifier for the private key |
|
||||
| `privateKey` | _string_ | PrivateKey is the PEM-encoded ES256 private key content (from .p8 file) |
|
||||
| `privateKeyFile` | _string_ | PrivateKeyFile is the path to the .p8 private key file |
|
||||
|
||||
### AzureOptions
|
||||
|
||||
(**Appears on:** [Provider](#provider))
|
||||
|
|
@ -552,6 +565,7 @@ character.
|
|||
| `audienceClaims` | _[]string_ | AudienceClaim allows to define any claim that is verified against the client id<br/>By default `aud` claim is used for verification. |
|
||||
| `extraAudiences` | _[]string_ | ExtraAudiences is a list of additional audiences that are allowed<br/>to pass verification in addition to the client id. |
|
||||
| `enabledSigningAlgs` | _[]string_ | EnabledSigningAlgs is a list of allowed JWT signing algorithms.<br/>When discovery is enabled, the effective set is the intersection<br/>between this list and the provider's discovered supported algorithms.<br/>By default `RS256` is used if nothing has been discovered or specified. |
|
||||
| `authStyle` | _string_ | AuthStyle specifies how the endpoint wants the client ID & client secret sent.<br/>Possible values are:<br/> - "inParams" (or "params"): sends credentials in the POST body as application/x-www-form-urlencoded parameters<br/> - "inHeader" (or "header"): sends credentials using HTTP Basic Authorization<br/> - "" (empty, default): auto-detect by trying both ways<br/>Some providers like Apple require "inParams". |
|
||||
|
||||
### Provider
|
||||
|
||||
|
|
@ -574,6 +588,7 @@ Provider holds all configuration for a single provider
|
|||
| `googleConfig` | _[GoogleOptions](#googleoptions)_ | GoogleConfig holds all configurations for Google provider. |
|
||||
| `oidcConfig` | _[OIDCOptions](#oidcoptions)_ | OIDCConfig holds all configurations for OIDC provider<br/>or providers utilize OIDC configurations. |
|
||||
| `loginGovConfig` | _[LoginGovOptions](#logingovoptions)_ | LoginGovConfig holds all configurations for LoginGov provider. |
|
||||
| `appleConfig` | _[AppleOptions](#appleoptions)_ | AppleConfig holds all configurations for Apple provider. |
|
||||
| `id` | _string_ | ID should be a unique identifier for the provider.<br/>This value is required for all providers. |
|
||||
| `provider` | _[ProviderType](#providertype)_ | Type is the OAuth provider<br/>must be set from the supported providers group,<br/>otherwise 'Google' is set as default |
|
||||
| `name` | _string_ | Name is the providers display name<br/>if set, it will be shown to the users in the login page. |
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ func providerRequiresClientSecret(provider options.Provider) bool {
|
|||
}
|
||||
|
||||
// Apple uses a private key to dynamically generate client_secret JWTs
|
||||
if provider.Type == "apple" {
|
||||
if provider.Type == options.AppleProvider {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package providers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
|
|
@ -11,11 +10,8 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
|
|
@ -63,16 +59,20 @@ func NewAppleProvider(p *ProviderData, appleOpts options.AppleOptions, oidcOpts
|
|||
validateURL: nil,
|
||||
scope: appleDefaultScope,
|
||||
})
|
||||
p.getAuthorizationHeaderFunc = makeOIDCHeader
|
||||
// Apple returns the authorization code via form POST rather than query
|
||||
// parameters, so default the response mode accordingly
|
||||
if p.AuthRequestResponseMode == "" {
|
||||
p.AuthRequestResponseMode = "form_post"
|
||||
}
|
||||
|
||||
oidcProvider := NewOIDCProvider(p, oidcOpts)
|
||||
// Apple requires the client credentials in the POST body
|
||||
oidcProvider.AuthStyle = oauth2.AuthStyleInParams
|
||||
|
||||
provider := &AppleProvider{
|
||||
OIDCProvider: &OIDCProvider{
|
||||
ProviderData: p,
|
||||
SkipNonce: true, // Apple doesn't use nonce in the standard way
|
||||
AuthStyle: oauth2.AuthStyleInParams, // Apple requires credentials in POST body
|
||||
},
|
||||
TeamID: appleOpts.TeamID,
|
||||
KeyID: appleOpts.KeyID,
|
||||
OIDCProvider: oidcProvider,
|
||||
TeamID: appleOpts.TeamID,
|
||||
KeyID: appleOpts.KeyID,
|
||||
}
|
||||
|
||||
if err := provider.initialize(appleOpts); err != nil {
|
||||
|
|
@ -167,34 +167,3 @@ func (p *AppleProvider) generateClientSecret() (string, error) {
|
|||
|
||||
return token.SignedString(p.PrivateKey)
|
||||
}
|
||||
|
||||
// GetLoginURL returns the Apple authorization URL with required parameters
|
||||
func (p *AppleProvider) GetLoginURL(redirectURI, state, nonce string, extraParams url.Values) string {
|
||||
// Apple requires response_mode=form_post for web clients
|
||||
if extraParams.Get("response_mode") == "" {
|
||||
extraParams.Set("response_mode", "form_post")
|
||||
}
|
||||
return p.OIDCProvider.GetLoginURL(redirectURI, state, nonce, extraParams)
|
||||
}
|
||||
|
||||
// ValidateSession validates the session's ID token
|
||||
func (p *AppleProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool {
|
||||
ctx = oidc.ClientContext(ctx, requests.DefaultHTTPClient)
|
||||
|
||||
// Validate ID token if present
|
||||
if s.IDToken != "" && p.Verifier != nil {
|
||||
if _, err := p.Verifier.Verify(ctx, s.IDToken); err != nil {
|
||||
return false
|
||||
}
|
||||
// ID token is valid - Apple doesn't provide a token validation endpoint
|
||||
return true
|
||||
}
|
||||
|
||||
// Fallback to access token validation if ValidateURL is set
|
||||
if p.ValidateURL != nil && p.ValidateURL.String() != "" {
|
||||
return validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken))
|
||||
}
|
||||
|
||||
// No validation possible, but session exists with valid data
|
||||
return s.AccessToken != ""
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue