@@ -1,4 +1,4 @@
1−package main
1+package validation
22
33import (
44 "context"
@@ -14,11 +14,11 @@ import (
1414 "strings"
1515 "time"
1616
17− oidc "github.com/coreos/go-oidc"
17+ "github.com/coreos/go-oidc"
1818 "github.com/dgrijalva/jwt-go"
1919 "github.com/mbland/hmacauth"
20+ "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/logging"
2021 "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options"
21− sessionsapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions"
2222 "github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
2323 "github.com/oauth2-proxy/oauth2-proxy/pkg/logger"
2424 "github.com/oauth2-proxy/oauth2-proxy/pkg/requests"
@@ -27,197 +27,9 @@ import (
2727 "gopkg.in/natefinch/lumberjack.v2"
2828)
2929
30−// Options holds Configuration Options that can be set by Command Line Flag,
31−// or Config File
32−type Options struct {
33− ProxyPrefix string `flag:"proxy-prefix" cfg:"proxy_prefix" env:"OAUTH2_PROXY_PROXY_PREFIX"`
34− PingPath string `flag:"ping-path" cfg:"ping_path" env:"OAUTH2_PROXY_PING_PATH"`
35− ProxyWebSockets bool `flag:"proxy-websockets" cfg:"proxy_websockets" env:"OAUTH2_PROXY_PROXY_WEBSOCKETS"`
36− HTTPAddress string `flag:"http-address" cfg:"http_address" env:"OAUTH2_PROXY_HTTP_ADDRESS"`
37− HTTPSAddress string `flag:"https-address" cfg:"https_address" env:"OAUTH2_PROXY_HTTPS_ADDRESS"`
38− ReverseProxy bool `flag:"reverse-proxy" cfg:"reverse_proxy" env:"OAUTH2_PROXY_REVERSE_PROXY"`
39− RealClientIPHeader string `flag:"real-client-ip-header" cfg:"real_client_ip_header" env:"OAUTH2_PROXY_REAL_CLIENT_IP_HEADER"`
40− ForceHTTPS bool `flag:"force-https" cfg:"force_https" env:"OAUTH2_PROXY_FORCE_HTTPS"`
41− RedirectURL string `flag:"redirect-url" cfg:"redirect_url" env:"OAUTH2_PROXY_REDIRECT_URL"`
42− ClientID string `flag:"client-id" cfg:"client_id" env:"OAUTH2_PROXY_CLIENT_ID"`
43− ClientSecret string `flag:"client-secret" cfg:"client_secret" env:"OAUTH2_PROXY_CLIENT_SECRET"`
44− ClientSecretFile string `flag:"client-secret-file" cfg:"client_secret_file" env:"OAUTH2_PROXY_CLIENT_SECRET_FILE"`
45− TLSCertFile string `flag:"tls-cert-file" cfg:"tls_cert_file" env:"OAUTH2_PROXY_TLS_CERT_FILE"`
46− TLSKeyFile string `flag:"tls-key-file" cfg:"tls_key_file" env:"OAUTH2_PROXY_TLS_KEY_FILE"`
47−
48− AuthenticatedEmailsFile string `flag:"authenticated-emails-file" cfg:"authenticated_emails_file" env:"OAUTH2_PROXY_AUTHENTICATED_EMAILS_FILE"`
49− KeycloakGroup string `flag:"keycloak-group" cfg:"keycloak_group" env:"OAUTH2_PROXY_KEYCLOAK_GROUP"`
50− AzureTenant string `flag:"azure-tenant" cfg:"azure_tenant" env:"OAUTH2_PROXY_AZURE_TENANT"`
51− BitbucketTeam string `flag:"bitbucket-team" cfg:"bitbucket_team" env:"OAUTH2_PROXY_BITBUCKET_TEAM"`
52− BitbucketRepository string `flag:"bitbucket-repository" cfg:"bitbucket_repository" env:"OAUTH2_PROXY_BITBUCKET_REPOSITORY"`
53− EmailDomains []string `flag:"email-domain" cfg:"email_domains" env:"OAUTH2_PROXY_EMAIL_DOMAINS"`
54− WhitelistDomains []string `flag:"whitelist-domain" cfg:"whitelist_domains" env:"OAUTH2_PROXY_WHITELIST_DOMAINS"`
55− GitHubOrg string `flag:"github-org" cfg:"github_org" env:"OAUTH2_PROXY_GITHUB_ORG"`
56− GitHubTeam string `flag:"github-team" cfg:"github_team" env:"OAUTH2_PROXY_GITHUB_TEAM"`
57− GitHubRepo string `flag:"github-repo" cfg:"github_repo" env:"OAUTH2_PROXY_GITHUB_REPO"`
58− GitHubToken string `flag:"github-token" cfg:"github_token" env:"OAUTH2_PROXY_GITHUB_TOKEN"`
59− GitLabGroup string `flag:"gitlab-group" cfg:"gitlab_group" env:"OAUTH2_PROXY_GITLAB_GROUP"`
60− GoogleGroups []string `flag:"google-group" cfg:"google_group" env:"OAUTH2_PROXY_GOOGLE_GROUPS"`
61− GoogleAdminEmail string `flag:"google-admin-email" cfg:"google_admin_email" env:"OAUTH2_PROXY_GOOGLE_ADMIN_EMAIL"`
62− GoogleServiceAccountJSON string `flag:"google-service-account-json" cfg:"google_service_account_json" env:"OAUTH2_PROXY_GOOGLE_SERVICE_ACCOUNT_JSON"`
63− HtpasswdFile string `flag:"htpasswd-file" cfg:"htpasswd_file" env:"OAUTH2_PROXY_HTPASSWD_FILE"`
64− DisplayHtpasswdForm bool `flag:"display-htpasswd-form" cfg:"display_htpasswd_form" env:"OAUTH2_PROXY_DISPLAY_HTPASSWD_FORM"`
65− CustomTemplatesDir string `flag:"custom-templates-dir" cfg:"custom_templates_dir" env:"OAUTH2_PROXY_CUSTOM_TEMPLATES_DIR"`
66− Banner string `flag:"banner" cfg:"banner" env:"OAUTH2_PROXY_BANNER"`
67− Footer string `flag:"footer" cfg:"footer" env:"OAUTH2_PROXY_FOOTER"`
68−
69− Cookie options.CookieOptions `cfg:",squash"`
70− Session options.SessionOptions `cfg:",squash"`
71−
72− Upstreams []string `flag:"upstream" cfg:"upstreams" env:"OAUTH2_PROXY_UPSTREAMS"`
73− SkipAuthRegex []string `flag:"skip-auth-regex" cfg:"skip_auth_regex" env:"OAUTH2_PROXY_SKIP_AUTH_REGEX"`
74− SkipJwtBearerTokens bool `flag:"skip-jwt-bearer-tokens" cfg:"skip_jwt_bearer_tokens" env:"OAUTH2_PROXY_SKIP_JWT_BEARER_TOKENS"`
75− ExtraJwtIssuers []string `flag:"extra-jwt-issuers" cfg:"extra_jwt_issuers" env:"OAUTH2_PROXY_EXTRA_JWT_ISSUERS"`
76− PassBasicAuth bool `flag:"pass-basic-auth" cfg:"pass_basic_auth" env:"OAUTH2_PROXY_PASS_BASIC_AUTH"`
77− SetBasicAuth bool `flag:"set-basic-auth" cfg:"set_basic_auth" env:"OAUTH2_PROXY_SET_BASIC_AUTH"`
78− PreferEmailToUser bool `flag:"prefer-email-to-user" cfg:"prefer_email_to_user" env:"OAUTH2_PROXY_PREFER_EMAIL_TO_USER"`
79− BasicAuthPassword string `flag:"basic-auth-password" cfg:"basic_auth_password" env:"OAUTH2_PROXY_BASIC_AUTH_PASSWORD"`
80− PassAccessToken bool `flag:"pass-access-token" cfg:"pass_access_token" env:"OAUTH2_PROXY_PASS_ACCESS_TOKEN"`
81− PassHostHeader bool `flag:"pass-host-header" cfg:"pass_host_header" env:"OAUTH2_PROXY_PASS_HOST_HEADER"`
82− SkipProviderButton bool `flag:"skip-provider-button" cfg:"skip_provider_button" env:"OAUTH2_PROXY_SKIP_PROVIDER_BUTTON"`
83− PassUserHeaders bool `flag:"pass-user-headers" cfg:"pass_user_headers" env:"OAUTH2_PROXY_PASS_USER_HEADERS"`
84− SSLInsecureSkipVerify bool `flag:"ssl-insecure-skip-verify" cfg:"ssl_insecure_skip_verify" env:"OAUTH2_PROXY_SSL_INSECURE_SKIP_VERIFY"`
85− SSLUpstreamInsecureSkipVerify bool `flag:"ssl-upstream-insecure-skip-verify" cfg:"ssl_upstream_insecure_skip_verify" env:"OAUTH2_PROXY_SSL_UPSTREAM_INSECURE_SKIP_VERIFY"`
86− SetXAuthRequest bool `flag:"set-xauthrequest" cfg:"set_xauthrequest" env:"OAUTH2_PROXY_SET_XAUTHREQUEST"`
87− SetAuthorization bool `flag:"set-authorization-header" cfg:"set_authorization_header" env:"OAUTH2_PROXY_SET_AUTHORIZATION_HEADER"`
88− PassAuthorization bool `flag:"pass-authorization-header" cfg:"pass_authorization_header" env:"OAUTH2_PROXY_PASS_AUTHORIZATION_HEADER"`
89− SkipAuthPreflight bool `flag:"skip-auth-preflight" cfg:"skip_auth_preflight" env:"OAUTH2_PROXY_SKIP_AUTH_PREFLIGHT"`
90− FlushInterval time.Duration `flag:"flush-interval" cfg:"flush_interval" env:"OAUTH2_PROXY_FLUSH_INTERVAL"`
91−
92− // These options allow for other providers besides Google, with
93− // potential overrides.
94− Provider string `flag:"provider" cfg:"provider" env:"OAUTH2_PROXY_PROVIDER"`
95− ProviderName string `flag:"provider-display-name" cfg:"provider_display_name" env:"OAUTH2_PROXY_PROVIDER_DISPLAY_NAME"`
96− OIDCIssuerURL string `flag:"oidc-issuer-url" cfg:"oidc_issuer_url" env:"OAUTH2_PROXY_OIDC_ISSUER_URL"`
97− InsecureOIDCAllowUnverifiedEmail bool `flag:"insecure-oidc-allow-unverified-email" cfg:"insecure_oidc_allow_unverified_email" env:"OAUTH2_PROXY_INSECURE_OIDC_ALLOW_UNVERIFIED_EMAIL"`
98− InsecureOIDCSkipIssuerVerification bool `flag:"insecure-oidc-skip-issuer-verification" cfg:"insecure_oidc_skip_issuer_verification" env:"OAUTH2_PROXY_INSECURE_OIDC_SKIP_ISSUER_VERIFICATION"`
99− SkipOIDCDiscovery bool `flag:"skip-oidc-discovery" cfg:"skip_oidc_discovery" env:"OAUTH2_PROXY_SKIP_OIDC_DISCOVERY"`
100− OIDCJwksURL string `flag:"oidc-jwks-url" cfg:"oidc_jwks_url" env:"OAUTH2_PROXY_OIDC_JWKS_URL"`
101− LoginURL string `flag:"login-url" cfg:"login_url" env:"OAUTH2_PROXY_LOGIN_URL"`
102− RedeemURL string `flag:"redeem-url" cfg:"redeem_url" env:"OAUTH2_PROXY_REDEEM_URL"`
103− ProfileURL string `flag:"profile-url" cfg:"profile_url" env:"OAUTH2_PROXY_PROFILE_URL"`
104− ProtectedResource string `flag:"resource" cfg:"resource" env:"OAUTH2_PROXY_RESOURCE"`
105− ValidateURL string `flag:"validate-url" cfg:"validate_url" env:"OAUTH2_PROXY_VALIDATE_URL"`
106− Scope string `flag:"scope" cfg:"scope" env:"OAUTH2_PROXY_SCOPE"`
107− Prompt string `flag:"prompt" cfg:"prompt" env:"OAUTH2_PROXY_PROMPT"`
108− ApprovalPrompt string `flag:"approval-prompt" cfg:"approval_prompt" env:"OAUTH2_PROXY_APPROVAL_PROMPT"` // Deprecated by OIDC 1.0
109− UserIDClaim string `flag:"user-id-claim" cfg:"user_id_claim" env:"OAUTH2_PROXY_USER_ID_CLAIM"`
110−
111− // Configuration values for logging
112− LoggingFilename string `flag:"logging-filename" cfg:"logging_filename" env:"OAUTH2_PROXY_LOGGING_FILENAME"`
113− LoggingMaxSize int `flag:"logging-max-size" cfg:"logging_max_size" env:"OAUTH2_PROXY_LOGGING_MAX_SIZE"`
114− LoggingMaxAge int `flag:"logging-max-age" cfg:"logging_max_age" env:"OAUTH2_PROXY_LOGGING_MAX_AGE"`
115− LoggingMaxBackups int `flag:"logging-max-backups" cfg:"logging_max_backups" env:"OAUTH2_PROXY_LOGGING_MAX_BACKUPS"`
116− LoggingLocalTime bool `flag:"logging-local-time" cfg:"logging_local_time" env:"OAUTH2_PROXY_LOGGING_LOCAL_TIME"`
117− LoggingCompress bool `flag:"logging-compress" cfg:"logging_compress" env:"OAUTH2_PROXY_LOGGING_COMPRESS"`
118− StandardLogging bool `flag:"standard-logging" cfg:"standard_logging" env:"OAUTH2_PROXY_STANDARD_LOGGING"`
119− StandardLoggingFormat string `flag:"standard-logging-format" cfg:"standard_logging_format" env:"OAUTH2_PROXY_STANDARD_LOGGING_FORMAT"`
120− RequestLogging bool `flag:"request-logging" cfg:"request_logging" env:"OAUTH2_PROXY_REQUEST_LOGGING"`
121− RequestLoggingFormat string `flag:"request-logging-format" cfg:"request_logging_format" env:"OAUTH2_PROXY_REQUEST_LOGGING_FORMAT"`
122− ExcludeLoggingPaths string `flag:"exclude-logging-paths" cfg:"exclude_logging_paths" env:"OAUTH2_PROXY_EXCLUDE_LOGGING_PATHS"`
123− SilencePingLogging bool `flag:"silence-ping-logging" cfg:"silence_ping_logging" env:"OAUTH2_PROXY_SILENCE_PING_LOGGING"`
124− AuthLogging bool `flag:"auth-logging" cfg:"auth_logging" env:"OAUTH2_PROXY_LOGGING_AUTH_LOGGING"`
125− AuthLoggingFormat string `flag:"auth-logging-format" cfg:"auth_logging_format" env:"OAUTH2_PROXY_AUTH_LOGGING_FORMAT"`
126− SignatureKey string `flag:"signature-key" cfg:"signature_key" env:"OAUTH2_PROXY_SIGNATURE_KEY"`
127− AcrValues string `flag:"acr-values" cfg:"acr_values" env:"OAUTH2_PROXY_ACR_VALUES"`
128− JWTKey string `flag:"jwt-key" cfg:"jwt_key" env:"OAUTH2_PROXY_JWT_KEY"`
129− JWTKeyFile string `flag:"jwt-key-file" cfg:"jwt_key_file" env:"OAUTH2_PROXY_JWT_KEY_FILE"`
130− PubJWKURL string `flag:"pubjwk-url" cfg:"pubjwk_url" env:"OAUTH2_PROXY_PUBJWK_URL"`
131− GCPHealthChecks bool `flag:"gcp-healthchecks" cfg:"gcp_healthchecks" env:"OAUTH2_PROXY_GCP_HEALTHCHECKS"`
132−
133− // internal values that are set after config validation
134− redirectURL *url.URL
135− proxyURLs []*url.URL
136− compiledRegex []*regexp.Regexp
137− provider providers.Provider
138− sessionStore sessionsapi.SessionStore
139− signatureData *SignatureData
140− oidcVerifier *oidc.IDTokenVerifier
141− jwtBearerVerifiers []*oidc.IDTokenVerifier
142− realClientIPParser realClientIPParser
143−}
144−
145−// SignatureData holds hmacauth signature hash and key
146−type SignatureData struct {
147− hash crypto.Hash
148− key string
149−}
150−
151−// NewOptions constructs a new Options with defaulted values
152−func NewOptions() *Options {
153− return &Options{
154− ProxyPrefix: "/oauth2",
155− PingPath: "/ping",
156− ProxyWebSockets: true,
157− HTTPAddress: "127.0.0.1:4180",
158− HTTPSAddress: ":443",
159− ForceHTTPS: false,
160− DisplayHtpasswdForm: true,
161− Cookie: options.CookieOptions{
162− Name: "_oauth2_proxy",
163− Secure: true,
164− HTTPOnly: true,
165− Expire: time.Duration(168) * time.Hour,
166− Refresh: time.Duration(0),
167− },
168− Session: options.SessionOptions{
169− Type: "cookie",
170− },
171− SetXAuthRequest: false,
172− SkipAuthPreflight: false,
173− PassBasicAuth: true,
174− SetBasicAuth: false,
175− PassUserHeaders: true,
176− PassAccessToken: false,
177− PassHostHeader: true,
178− SetAuthorization: false,
179− PassAuthorization: false,
180− PreferEmailToUser: false,
181− Prompt: "", // Change to "login" when ApprovalPrompt officially deprecated
182− ApprovalPrompt: "force",
183− UserIDClaim: "email",
184− InsecureOIDCAllowUnverifiedEmail: false,
185− SkipOIDCDiscovery: false,
186− LoggingFilename: "",
187− LoggingMaxSize: 100,
188− LoggingMaxAge: 7,
189− LoggingMaxBackups: 0,
190− LoggingLocalTime: true,
191− LoggingCompress: false,
192− ExcludeLoggingPaths: "",
193− SilencePingLogging: false,
194− StandardLogging: true,
195− StandardLoggingFormat: logger.DefaultStandardLoggingFormat,
196− RequestLogging: true,
197− RequestLoggingFormat: logger.DefaultRequestLoggingFormat,
198− AuthLogging: true,
199− AuthLoggingFormat: logger.DefaultAuthLoggingFormat,
200− }
201−}
202−
203−// jwtIssuer hold parsed JWT issuer info that's used to construct a verifier.
204−type jwtIssuer struct {
205− issuerURI string
206− audience string
207−}
208−
209−func parseURL(toParse string, urltype string, msgs []string) (*url.URL, []string) {
210− parsed, err := url.Parse(toParse)
211− if err != nil {
212− return nil, append(msgs, fmt.Sprintf(
213− "error parsing %s-url=%q %s", urltype, toParse, err))
214− }
215− return parsed, msgs
216−}
217−
21830// Validate checks that required options are set and validates those that they
21931// are of the correct format
220−func (o *Options) Validate() error {
32+func Validate(o *options.Options) error {
22133 if o.SSLInsecureSkipVerify {
22234 // TODO: Accept a certificate bundle.
22335 insecureTransport := &http.Transport{
@@ -234,7 +46,7 @@ func (o *Options) Validate() error {
23446 msgs = append(msgs, "missing setting: client-id")
23547 }
23648 // login.gov uses a signed JWT to authenticate, not a client-secret
237− if o.Provider != "login.gov" {
49+ if o.ProviderType != "login.gov" {
23850 if o.ClientSecret == "" && o.ClientSecretFile == "" {
23951 msgs = append(msgs, "missing setting: client-secret or client-secret-file")
24052 }
@@ -311,20 +123,20 @@ func (o *Options) Validate() error {
311123 msgs = append(msgs, "missing setting: oidc-jwks-url")
312124 }
313125 keySet := oidc.NewRemoteKeySet(ctx, o.OIDCJwksURL)
314− o.oidcVerifier = oidc.NewVerifier(o.OIDCIssuerURL, keySet, &oidc.Config{
126+ o.SetOIDCVerifier(oidc.NewVerifier(o.OIDCIssuerURL, keySet, &oidc.Config{
315127 ClientID: o.ClientID,
316128 SkipIssuerCheck: o.InsecureOIDCSkipIssuerVerification,
317− })
129+ }))
318130 } else {
319131 // Configure discoverable provider data.
320132 provider, err := oidc.NewProvider(ctx, o.OIDCIssuerURL)
321133 if err != nil {
322134 return err
323135 }
324− o.oidcVerifier = provider.Verifier(&oidc.Config{
136+ o.SetOIDCVerifier(provider.Verifier(&oidc.Config{
325137 ClientID: o.ClientID,
326138 SkipIssuerCheck: o.InsecureOIDCSkipIssuerVerification,
327− })
139+ }))
328140
329141 o.LoginURL = provider.Endpoint().AuthURL
330142 o.RedeemURL = provider.Endpoint().TokenURL
@@ -340,8 +152,8 @@ func (o *Options) Validate() error {
340152
341153 if o.SkipJwtBearerTokens {
342154 // If we are using an oidc provider, go ahead and add that provider to the list
343− if o.oidcVerifier != nil {
344− o.jwtBearerVerifiers = append(o.jwtBearerVerifiers, o.oidcVerifier)
155+ if o.GetOIDCVerifier() != nil {
156+ o.SetJWTBearerVerifiers(append(o.GetJWTBearerVerifiers(), o.GetOIDCVerifier()))
345157 }
346158 // Configure extra issuers
347159 if len(o.ExtraJwtIssuers) > 0 {
@@ -352,12 +164,14 @@ func (o *Options) Validate() error {
352164 if err != nil {
353165 msgs = append(msgs, fmt.Sprintf("error building verifiers: %s", err))
354166 }
355− o.jwtBearerVerifiers = append(o.jwtBearerVerifiers, verifier)
167+ o.SetJWTBearerVerifiers(append(o.GetJWTBearerVerifiers(), verifier))
356168 }
357169 }
358170 }
359171
360− o.redirectURL, msgs = parseURL(o.RedirectURL, "redirect", msgs)
172+ var redirectURL *url.URL
173+ redirectURL, msgs = parseURL(o.RawRedirectURL, "redirect", msgs)
174+ o.SetRedirectURL(redirectURL)
361175
362176 for _, u := range o.Upstreams {
363177 upstreamURL, err := url.Parse(u)
@@ -367,7 +181,7 @@ func (o *Options) Validate() error {
367181 if upstreamURL.Path == "" {
368182 upstreamURL.Path = "/"
369183 }
370− o.proxyURLs = append(o.proxyURLs, upstreamURL)
184+ o.SetProxyURLs(append(o.GetProxyURLs(), upstreamURL))
371185 }
372186 }
373187
@@ -377,7 +191,7 @@ func (o *Options) Validate() error {
377191 msgs = append(msgs, fmt.Sprintf("error compiling regex=%q %s", u, err))
378192 continue
379193 }
380− o.compiledRegex = append(o.compiledRegex, compiledRegex)
194+ o.SetCompiledRegex(append(o.GetCompiledRegex(), compiledRegex))
381195 }
382196 msgs = parseProviderInfo(o, msgs)
383197
@@ -418,7 +232,7 @@ func (o *Options) Validate() error {
418232 if err != nil {
419233 msgs = append(msgs, fmt.Sprintf("error initialising session storage: %v", err))
420234 } else {
421− o.sessionStore = sessionStore
235+ o.SetSessionStore(sessionStore)
422236 }
423237
424238 if o.Cookie.Refresh >= o.Cookie.Expire {
@@ -458,10 +272,11 @@ func (o *Options) Validate() error {
458272 msgs = setupLogger(o, msgs)
459273
460274 if o.ReverseProxy {
461− o.realClientIPParser, err = getRealClientIPParser(o.RealClientIPHeader)
275+ parser, err := logging.GetRealClientIPParser(o.RealClientIPHeader)
462276 if err != nil {
463277 msgs = append(msgs, fmt.Sprintf("real_client_ip_header (%s) not accepted parameter value: %v", o.RealClientIPHeader, err))
464278 }
279+ o.SetRealClientIPParser(parser)
465280 }
466281
467282 if len(msgs) != 0 {
@@ -471,7 +286,7 @@ func (o *Options) Validate() error {
471286 return nil
472287}
473288
474−func parseProviderInfo(o *Options, msgs []string) []string {
289+func parseProviderInfo(o *options.Options, msgs []string) []string {
475290 p := &providers.ProviderData{
476291 Scope: o.Scope,
477292 ClientID: o.ClientID,
@@ -487,8 +302,8 @@ func parseProviderInfo(o *Options, msgs []string) []string {
487302 p.ValidateURL, msgs = parseURL(o.ValidateURL, "validate", msgs)
488303 p.ProtectedResource, msgs = parseURL(o.ProtectedResource, "resource", msgs)
489304
490− o.provider = providers.New(o.Provider, p)
491− switch p := o.provider.(type) {
305+ o.SetProvider(providers.New(o.ProviderType, p))
306+ switch p := o.GetProvider().(type) {
492307 case *providers.AzureProvider:
493308 p.Configure(o.AzureTenant)
494309 case *providers.GitHubProvider:
@@ -511,18 +326,18 @@ func parseProviderInfo(o *Options, msgs []string) []string {
511326 case *providers.OIDCProvider:
512327 p.AllowUnverifiedEmail = o.InsecureOIDCAllowUnverifiedEmail
513328 p.UserIDClaim = o.UserIDClaim
514− if o.oidcVerifier == nil {
329+ if o.GetOIDCVerifier() == nil {
515330 msgs = append(msgs, "oidc provider requires an oidc issuer URL")
516331 } else {
517− p.Verifier = o.oidcVerifier
332+ p.Verifier = o.GetOIDCVerifier()
518333 }
519334 case *providers.GitLabProvider:
520335 p.AllowUnverifiedEmail = o.InsecureOIDCAllowUnverifiedEmail
521336 p.Group = o.GitLabGroup
522337 p.EmailDomains = o.EmailDomains
523338
524− if o.oidcVerifier != nil {
525− p.Verifier = o.oidcVerifier
339+ if o.GetOIDCVerifier() != nil {
340+ p.Verifier = o.GetOIDCVerifier()
526341 } else {
527342 // Initialize with default verifier for gitlab.com
528343 ctx := context.Background()
@@ -573,7 +388,7 @@ func parseProviderInfo(o *Options, msgs []string) []string {
573388 return msgs
574389}
575390
576−func parseSignatureKey(o *Options, msgs []string) []string {
391+func parseSignatureKey(o *options.Options, msgs []string) []string {
577392 if o.SignatureKey == "" {
578393 return msgs
579394 }
@@ -591,7 +406,7 @@ func parseSignatureKey(o *Options, msgs []string) []string {
591406 return append(msgs, "unsupported signature hash algorithm: "+
592407 o.SignatureKey)
593408 }
594− o.signatureData = &SignatureData{hash: hash, key: secretKey}
409+ o.SetSignatureData(&options.SignatureData{Hash: hash, Key: secretKey})
595410 return msgs
596411}
597412
@@ -634,7 +449,7 @@ func newVerifierFromJwtIssuer(jwtIssuer jwtIssuer) (*oidc.IDTokenVerifier, error
634449 return verifier, nil
635450}
636451
637−func validateCookieName(o *Options, msgs []string) []string {
452+func validateCookieName(o *options.Options, msgs []string) []string {
638453 cookie := &http.Cookie{Name: o.Cookie.Name}
639454 if cookie.String() == "" {
640455 return append(msgs, fmt.Sprintf("invalid cookie name: %q", o.Cookie.Name))
@@ -642,7 +457,7 @@ func validateCookieName(o *Options, msgs []string) []string {
642457 return msgs
643458}
644459
645−func setupLogger(o *Options, msgs []string) []string {
460+func setupLogger(o *options.Options, msgs []string) []string {
646461 // Setup the log file
647462 if len(o.LoggingFilename) > 0 {
648463 // Validate that the file/dir can be written
@@ -681,7 +496,7 @@ func setupLogger(o *Options, msgs []string) []string {
681496 logger.SetAuthTemplate(o.AuthLoggingFormat)
682497 logger.SetReqTemplate(o.RequestLoggingFormat)
683498 logger.SetGetClientFunc(func(r *http.Request) string {
684− return getClientString(o.realClientIPParser, r, false)
499+ return logging.GetClientString(o.GetRealClientIPParser(), r, false)
685500 })
686501
687502 excludePaths := make([]string, 0)
@@ -698,3 +513,18 @@ func setupLogger(o *Options, msgs []string) []string {
698513
699514 return msgs
700515}
516+
517+// jwtIssuer hold parsed JWT issuer info that's used to construct a verifier.
518+type jwtIssuer struct {
519+ issuerURI string
520+ audience string
521+}
522+
523+func parseURL(toParse string, urltype string, msgs []string) (*url.URL, []string) {
524+ parsed, err := url.Parse(toParse)
525+ if err != nil {
526+ return nil, append(msgs, fmt.Sprintf(
527+ "error parsing %s-url=%q %s", urltype, toParse, err))
528+ }
529+ return parsed, msgs
530+}