8 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
9 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
10 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
11 internaloidc "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/providers/oidc"
12 "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/util/ptr"
13 k8serrors "k8s.io/apimachinery/pkg/util/errors"
17 CodeChallengeMethodPlain = "plain"
18 CodeChallengeMethodS256 = "S256"
21// Provider represents an upstream identity provider implementation
22type Provider interface {
24 GetLoginURL(redirectURI, finalRedirect, nonce string, extraParams url.Values) string
25 Redeem(ctx context.Context, redirectURI, code, codeVerifier string) (*sessions.SessionState, error)
26 // Deprecated: Migrate to EnrichSession
27 GetEmailAddress(ctx context.Context, s *sessions.SessionState) (string, error)
28 EnrichSession(ctx context.Context, s *sessions.SessionState) error
29 Authorize(ctx context.Context, s *sessions.SessionState) (bool, error)
30 ValidateSession(ctx context.Context, s *sessions.SessionState) bool
31 RefreshSession(ctx context.Context, s *sessions.SessionState) (bool, error)
32 CreateSessionFromToken(ctx context.Context, token string) (*sessions.SessionState, error)
35func NewProvider(providerConfig options.Provider) (Provider, error) {
36 providerData, err := newProviderDataFromConfig(providerConfig)
38 return nil, fmt.Errorf("could not create provider data: %v", err)
40 switch providerConfig.Type {
41 case options.ADFSProvider:
42 return NewADFSProvider(providerData, providerConfig), nil
43 case options.AtlassianProvider:
44 return NewAtlassianProvider(providerData), nil
45 case options.AzureProvider:
46 return NewAzureProvider(providerData, providerConfig.AzureConfig), nil
47 case options.MicrosoftEntraIDProvider:
48 return NewMicrosoftEntraIDProvider(providerData, providerConfig), nil
49 case options.BitbucketProvider:
50 return NewBitbucketProvider(providerData, providerConfig.BitbucketConfig), nil
51 case options.CidaasProvider:
52 return NewCIDAASProvider(providerData, providerConfig), nil
53 case options.DigitalOceanProvider:
54 return NewDigitalOceanProvider(providerData), nil
55 case options.DTTSSOProvider:
56 return NewDTTSSOProvider(providerData), nil
57 case options.FacebookProvider:
58 return NewFacebookProvider(providerData), nil
59 case options.GitHubProvider:
60 return NewGitHubProvider(providerData, providerConfig.GitHubConfig), nil
61 case options.GitLabProvider:
62 return NewGitLabProvider(providerData, providerConfig)
63 case options.GoogleProvider:
64 return NewGoogleProvider(providerData, providerConfig.GoogleConfig)
65 case options.KeycloakProvider:
66 return NewKeycloakProvider(providerData, providerConfig.KeycloakConfig), nil
67 case options.KeycloakOIDCProvider:
68 return NewKeycloakOIDCProvider(providerData, providerConfig), nil
69 case options.LinkedInProvider:
70 return NewLinkedInProvider(providerData), nil
71 case options.LoginGovProvider:
72 return NewLoginGovProvider(providerData, providerConfig.LoginGovConfig)
73 case options.NextCloudProvider:
74 return NewNextcloudProvider(providerData), nil
75 case options.OIDCProvider:
76 return NewOIDCProvider(providerData, providerConfig.OIDCConfig), nil
77 case options.SourceHutProvider:
78 return NewSourceHutProvider(providerData), nil
80 return nil, fmt.Errorf("unknown provider type %q", providerConfig.Type)
84func newProviderDataFromConfig(providerConfig options.Provider) (*ProviderData, error) {
86 Scope: providerConfig.Scope,
87 ClientID: providerConfig.ClientID,
88 ClientSecret: providerConfig.ClientSecret,
89 ClientSecretFile: providerConfig.ClientSecretFile,
90 AuthRequestResponseMode: providerConfig.AuthRequestResponseMode,
91 AdditionalClaims: providerConfig.AdditionalClaims,
94 needsVerifier, err := providerRequiresOIDCProviderVerifier(providerConfig.Type)
100 pv, err := internaloidc.NewProviderVerifier(context.TODO(), internaloidc.ProviderVerifierOptions{
101 AudienceClaims: providerConfig.OIDCConfig.AudienceClaims,
102 ClientID: providerConfig.ClientID,
103 ExtraAudiences: providerConfig.OIDCConfig.ExtraAudiences,
104 IssuerURL: providerConfig.OIDCConfig.IssuerURL,
105 JWKsURL: providerConfig.OIDCConfig.JwksURL,
106 PublicKeyFiles: providerConfig.OIDCConfig.PublicKeyFiles,
107 SupportedSigningAlgs: providerConfig.OIDCConfig.EnabledSigningAlgs,
108 SkipDiscovery: ptr.Deref(providerConfig.OIDCConfig.SkipDiscovery, options.DefaultSkipDiscovery),
109 SkipIssuerVerification: ptr.Deref(providerConfig.OIDCConfig.InsecureSkipIssuerVerification, options.DefaultInsecureSkipIssuerVerification),
112 return nil, fmt.Errorf("error building OIDC ProviderVerifier: %v", err)
115 p.Verifier = pv.Verifier()
116 if pv.DiscoveryEnabled() {
117 // Use the discovered values rather than any specified values
118 endpoints := pv.Provider().Endpoints()
119 pkce := pv.Provider().PKCE()
120 providerConfig.LoginURL = endpoints.AuthURL
121 providerConfig.RedeemURL = endpoints.TokenURL
122 providerConfig.ProfileURL = endpoints.UserInfoURL
123 providerConfig.OIDCConfig.JwksURL = endpoints.JWKsURL
124 p.SupportedCodeChallengeMethods = pkce.CodeChallengeAlgs
129 for name, u := range map[string]struct {
133 "login": {dst: &p.LoginURL, raw: providerConfig.LoginURL},
134 "redeem": {dst: &p.RedeemURL, raw: providerConfig.RedeemURL},
135 "profile": {dst: &p.ProfileURL, raw: providerConfig.ProfileURL},
136 "validate": {dst: &p.ValidateURL, raw: providerConfig.ValidateURL},
137 "resource": {dst: &p.ProtectedResource, raw: providerConfig.ProtectedResource},
140 *u.dst, err = url.Parse(u.raw)
142 errs = append(errs, fmt.Errorf("could not parse %s URL: %v", name, err))
145 // handle LoginURLParameters
146 errs = append(errs, p.compileLoginParams(providerConfig.LoginURLParameters)...)
149 return nil, k8serrors.NewAggregate(errs)
152 // Make the OIDC options available to all providers that support it
153 p.AllowUnverifiedEmail = ptr.Deref(providerConfig.OIDCConfig.InsecureAllowUnverifiedEmail, options.DefaultInsecureAllowUnverifiedEmail)
154 p.EmailClaim = providerConfig.OIDCConfig.EmailClaim
155 p.GroupsClaim = providerConfig.OIDCConfig.GroupsClaim
156 p.SkipClaimsFromProfileURL = ptr.Deref(providerConfig.SkipClaimsFromProfileURL, options.DefaultSkipClaimsFromProfileURL)
158 // Set PKCE enabled or disabled based on discovery and force options
159 p.CodeChallengeMethod = parseCodeChallengeMethod(providerConfig)
160 if len(p.SupportedCodeChallengeMethods) != 0 && p.CodeChallengeMethod == "" {
161 logger.Printf("Warning: Your provider supports PKCE methods %+q, but you have not enabled one with --code-challenge-method", p.SupportedCodeChallengeMethods)
164 if providerConfig.OIDCConfig.UserIDClaim == "" {
165 providerConfig.OIDCConfig.UserIDClaim = "email"
168 // TODO (@NickMeves) - Remove This
169 // Backwards Compatibility for Deprecated UserIDClaim option
170 if providerConfig.OIDCConfig.EmailClaim == options.OIDCEmailClaim &&
171 providerConfig.OIDCConfig.UserIDClaim != options.OIDCEmailClaim {
172 p.EmailClaim = providerConfig.OIDCConfig.UserIDClaim
175 p.setAllowedGroups(providerConfig.AllowedGroups)
177 p.BackendLogoutURL = providerConfig.BackendLogoutURL
182// Pick the most appropriate code challenge method for PKCE
183// At this time we do not consider what the server supports to be safe and
184// only enable PKCE if the user opts-in
185func parseCodeChallengeMethod(providerConfig options.Provider) string {
187 case providerConfig.CodeChallengeMethod != "":
188 return providerConfig.CodeChallengeMethod
194func providerRequiresOIDCProviderVerifier(providerType options.ProviderType) (bool, error) {
195 switch providerType {
196 case options.AtlassianProvider, options.BitbucketProvider, options.DigitalOceanProvider, options.DTTSSOProvider,
197 options.FacebookProvider, options.GitHubProvider, options.GoogleProvider, options.KeycloakProvider,
198 options.LinkedInProvider, options.LoginGovProvider, options.NextCloudProvider, options.SourceHutProvider:
200 case options.OIDCProvider, options.ADFSProvider, options.AzureProvider, options.CidaasProvider,
201 options.GitLabProvider, options.KeycloakOIDCProvider, options.MicrosoftEntraIDProvider:
204 return false, fmt.Errorf("unknown provider type: %s", providerType)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list