2016-08-19 14:51:40 +00:00
/ *
Copyright 2015 The Kubernetes Authors .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package authreq
import (
2018-11-27 16:12:17 +00:00
"fmt"
2017-02-04 00:43:15 +00:00
"regexp"
2017-04-02 14:07:07 +00:00
"strings"
2016-08-19 14:51:40 +00:00
2020-08-08 23:31:02 +00:00
"k8s.io/klog/v2"
2018-10-29 21:34:44 +00:00
2021-08-21 20:42:00 +00:00
networking "k8s.io/api/networking/v1"
2023-07-22 03:32:07 +00:00
"k8s.io/client-go/tools/cache"
2016-11-16 18:24:26 +00:00
2017-11-07 22:02:12 +00:00
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
ing_errors "k8s.io/ingress-nginx/internal/ingress/errors"
2017-11-08 20:58:57 +00:00
"k8s.io/ingress-nginx/internal/ingress/resolver"
2022-07-20 21:15:03 +00:00
"k8s.io/ingress-nginx/pkg/util/sets"
2016-08-19 14:51:40 +00:00
)
2023-07-22 03:32:07 +00:00
const (
2023-08-07 13:16:32 +00:00
authReqURLAnnotation = "auth-url"
authReqMethodAnnotation = "auth-method"
authReqSigninAnnotation = "auth-signin"
authReqSigninRedirParamAnnotation = "auth-signin-redirect-param"
authReqSnippetAnnotation = "auth-snippet"
authReqCacheKeyAnnotation = "auth-cache-key"
authReqKeepaliveAnnotation = "auth-keepalive"
authReqKeepaliveShareVarsAnnotation = "auth-keepalive-share-vars"
authReqKeepaliveRequestsAnnotation = "auth-keepalive-requests"
authReqKeepaliveTimeout = "auth-keepalive-timeout"
authReqCacheDuration = "auth-cache-duration"
authReqResponseHeadersAnnotation = "auth-response-headers"
authReqProxySetHeadersAnnotation = "auth-proxy-set-headers"
authReqRequestRedirectAnnotation = "auth-request-redirect"
authReqAlwaysSetCookieAnnotation = "auth-always-set-cookie"
2023-07-22 03:32:07 +00:00
// This should be exported as it is imported by other packages
AuthSecretAnnotation = "auth-secret"
)
var authReqAnnotations = parser . Annotation {
Group : "authentication" ,
Annotations : parser . AnnotationFields {
authReqURLAnnotation : {
2023-08-31 07:36:48 +00:00
Validator : parser . ValidateRegex ( parser . URLWithNginxVariableRegex , true ) ,
2023-07-22 03:32:07 +00:00
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskHigh ,
Documentation : ` This annotation allows to indicate the URL where the HTTP request should be sent ` ,
} ,
authReqMethodAnnotation : {
2023-08-31 07:36:48 +00:00
Validator : parser . ValidateRegex ( methodsRegex , true ) ,
2023-07-22 03:32:07 +00:00
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskLow ,
Documentation : ` This annotation allows to specify the HTTP method to use ` ,
} ,
authReqSigninAnnotation : {
2023-08-31 07:36:48 +00:00
Validator : parser . ValidateRegex ( parser . URLWithNginxVariableRegex , true ) ,
2023-07-22 03:32:07 +00:00
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskHigh ,
Documentation : ` This annotation allows to specify the location of the error page ` ,
} ,
authReqSigninRedirParamAnnotation : {
2023-08-31 07:36:48 +00:00
Validator : parser . ValidateRegex ( parser . URLIsValidRegex , true ) ,
2023-07-22 03:32:07 +00:00
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskMedium ,
Documentation : ` This annotation allows to specify the URL parameter in the error page which should contain the original URL for a failed signin request ` ,
} ,
authReqSnippetAnnotation : {
Validator : parser . ValidateNull ,
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskCritical ,
Documentation : ` This annotation allows to specify a custom snippet to use with external authentication ` ,
} ,
authReqCacheKeyAnnotation : {
2023-08-31 07:36:48 +00:00
Validator : parser . ValidateRegex ( parser . NGINXVariable , true ) ,
2023-07-22 03:32:07 +00:00
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskMedium ,
Documentation : ` This annotation enables caching for auth requests. ` ,
} ,
authReqKeepaliveAnnotation : {
Validator : parser . ValidateInt ,
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskLow ,
Documentation : ` This annotation specifies the maximum number of keepalive connections to auth-url. Only takes effect when no variables are used in the host part of the URL ` ,
} ,
2023-08-07 13:16:32 +00:00
authReqKeepaliveShareVarsAnnotation : {
Validator : parser . ValidateBool ,
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskLow ,
Documentation : ` This annotation specifies whether to share Nginx variables among the current request and the auth request ` ,
} ,
2023-07-22 03:32:07 +00:00
authReqKeepaliveRequestsAnnotation : {
Validator : parser . ValidateInt ,
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskLow ,
Documentation : ` This annotation defines the maximum number of requests that can be served through one keepalive connection ` ,
} ,
authReqKeepaliveTimeout : {
Validator : parser . ValidateInt ,
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskLow ,
Documentation : ` This annotation specifies a duration in seconds which an idle keepalive connection to an upstream server will stay open ` ,
} ,
authReqCacheDuration : {
2023-08-31 07:36:48 +00:00
Validator : parser . ValidateRegex ( parser . ExtendedCharsRegex , false ) ,
2023-07-22 03:32:07 +00:00
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskMedium ,
Documentation : ` This annotation allows to specify a caching time for auth responses based on their response codes, e.g. 200 202 30m ` ,
} ,
authReqResponseHeadersAnnotation : {
2023-08-31 07:36:48 +00:00
Validator : parser . ValidateRegex ( parser . HeadersVariable , true ) ,
2023-07-22 03:32:07 +00:00
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskMedium ,
Documentation : ` This annotation sets the headers to pass to backend once authentication request completes. They should be separated by comma. ` ,
} ,
authReqProxySetHeadersAnnotation : {
2023-08-31 07:36:48 +00:00
Validator : parser . ValidateRegex ( parser . BasicCharsRegex , true ) ,
2023-07-22 03:32:07 +00:00
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskMedium ,
Documentation : ` This annotation sets the name of a ConfigMap that specifies headers to pass to the authentication service .
Only ConfigMaps on the same namespace are allowed ` ,
} ,
authReqRequestRedirectAnnotation : {
2023-08-31 07:36:48 +00:00
Validator : parser . ValidateRegex ( parser . URLIsValidRegex , true ) ,
2023-07-22 03:32:07 +00:00
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskMedium ,
Documentation : ` This annotation allows to specify the X-Auth-Request-Redirect header value ` ,
} ,
authReqAlwaysSetCookieAnnotation : {
Validator : parser . ValidateBool ,
Scope : parser . AnnotationScopeLocation ,
Risk : parser . AnnotationRiskLow ,
Documentation : ` This annotation enables setting a cookie returned by auth request .
By default , the cookie will be set only if an upstream reports with the code 200 , 201 , 204 , 206 , 301 , 302 , 303 , 304 , 307 , or 308 ` ,
} ,
} ,
}
2017-11-08 20:58:57 +00:00
// Config returns external authentication configuration for an Ingress rule
2017-11-07 16:36:51 +00:00
type Config struct {
2017-04-25 01:14:38 +00:00
URL string ` json:"url" `
// Host contains the hostname defined in the URL
2020-08-18 09:03:38 +00:00
Host string ` json:"host" `
SigninURL string ` json:"signinUrl" `
SigninURLRedirectParam string ` json:"signinUrlRedirectParam,omitempty" `
Method string ` json:"method" `
ResponseHeaders [ ] string ` json:"responseHeaders,omitempty" `
RequestRedirect string ` json:"requestRedirect" `
AuthSnippet string ` json:"authSnippet" `
AuthCacheKey string ` json:"authCacheKey" `
AuthCacheDuration [ ] string ` json:"authCacheDuration" `
2022-04-09 03:22:04 +00:00
KeepaliveConnections int ` json:"keepaliveConnections" `
2023-08-07 13:16:32 +00:00
KeepaliveShareVars bool ` json:"keepaliveShareVars" `
2022-04-09 03:22:04 +00:00
KeepaliveRequests int ` json:"keepaliveRequests" `
KeepaliveTimeout int ` json:"keepaliveTimeout" `
2020-08-18 09:03:38 +00:00
ProxySetHeaders map [ string ] string ` json:"proxySetHeaders,omitempty" `
2022-05-19 22:27:53 +00:00
AlwaysSetCookie bool ` json:"alwaysSetCookie,omitempty" `
2016-08-19 14:51:40 +00:00
}
2019-07-07 16:34:56 +00:00
// DefaultCacheDuration is the fallback value if no cache duration is provided
const DefaultCacheDuration = "200 202 401 5m"
2022-04-09 03:22:04 +00:00
// fallback values when no keepalive parameters are set
const (
defaultKeepaliveConnections = 0
2023-08-07 13:16:32 +00:00
defaultKeepaliveShareVars = false
2022-04-09 03:22:04 +00:00
defaultKeepaliveRequests = 1000
defaultKeepaliveTimeout = 60
)
2017-11-07 16:36:51 +00:00
// Equal tests for equality between two Config types
func ( e1 * Config ) Equal ( e2 * Config ) bool {
2017-06-14 21:33:12 +00:00
if e1 == e2 {
return true
}
if e1 == nil || e2 == nil {
return false
}
if e1 . URL != e2 . URL {
return false
}
if e1 . Host != e2 . Host {
return false
}
if e1 . SigninURL != e2 . SigninURL {
return false
}
2020-08-18 09:03:38 +00:00
if e1 . SigninURLRedirectParam != e2 . SigninURLRedirectParam {
return false
}
2017-06-14 21:33:12 +00:00
if e1 . Method != e2 . Method {
return false
}
2019-04-02 13:56:12 +00:00
match := sets . StringElementsMatch ( e1 . ResponseHeaders , e2 . ResponseHeaders )
if ! match {
return false
2017-06-14 21:33:12 +00:00
}
2019-04-02 13:56:12 +00:00
2018-01-28 00:32:08 +00:00
if e1 . RequestRedirect != e2 . RequestRedirect {
return false
}
2018-10-29 21:34:44 +00:00
if e1 . AuthSnippet != e2 . AuthSnippet {
return false
}
2017-06-14 21:33:12 +00:00
2019-07-07 16:34:56 +00:00
if e1 . AuthCacheKey != e2 . AuthCacheKey {
return false
}
2022-04-09 03:22:04 +00:00
if e1 . KeepaliveConnections != e2 . KeepaliveConnections {
return false
}
2023-08-07 13:16:32 +00:00
if e1 . KeepaliveShareVars != e2 . KeepaliveShareVars {
return false
}
2022-04-09 03:22:04 +00:00
if e1 . KeepaliveRequests != e2 . KeepaliveRequests {
return false
}
if e1 . KeepaliveTimeout != e2 . KeepaliveTimeout {
return false
}
2022-05-19 22:27:53 +00:00
if e1 . AlwaysSetCookie != e2 . AlwaysSetCookie {
return false
}
2019-08-09 12:44:14 +00:00
return sets . StringElementsMatch ( e1 . AuthCacheDuration , e2 . AuthCacheDuration )
2017-06-14 21:33:12 +00:00
}
2016-08-19 14:51:40 +00:00
var (
2023-07-22 03:32:07 +00:00
methodsRegex = regexp . MustCompile ( "(GET|HEAD|POST|PUT|PATCH|DELETE|CONNECT|OPTIONS|TRACE)" )
2019-07-07 16:34:56 +00:00
headerRegexp = regexp . MustCompile ( ` ^[a-zA-Z\d\-_]+$ ` )
2023-08-31 07:36:48 +00:00
statusCodeRegex = regexp . MustCompile ( ` ^\d { 3}$ ` )
durationRegex = regexp . MustCompile ( ` ^\d+(ms|s|m|h|d|w|M|y)$ ` ) // see http://nginx.org/en/docs/syntax.html
2016-08-19 14:51:40 +00:00
)
2018-11-27 16:12:17 +00:00
// ValidMethod checks is the provided string a valid HTTP method
func ValidMethod ( method string ) bool {
2023-07-22 03:32:07 +00:00
return methodsRegex . MatchString ( method )
2016-08-19 14:51:40 +00:00
}
2018-11-27 16:12:17 +00:00
// ValidHeader checks is the provided string satisfies the header's name regex
func ValidHeader ( header string ) bool {
2023-06-01 14:29:47 +00:00
return headerRegexp . MatchString ( header )
2017-02-04 00:43:15 +00:00
}
2019-07-07 16:34:56 +00:00
// ValidCacheDuration checks if the provided string is a valid cache duration
// spec: [code ...] [time ...];
// with: code is an http status code
2022-12-29 22:09:29 +00:00
//
// time must match the time regex and may appear multiple times, e.g. `1h 30m`
2019-07-07 16:34:56 +00:00
func ValidCacheDuration ( duration string ) bool {
elements := strings . Split ( duration , " " )
seenDuration := false
for _ , element := range elements {
2023-08-31 07:36:48 +00:00
if element == "" {
2019-07-07 16:34:56 +00:00
continue
}
2023-06-01 14:29:47 +00:00
if statusCodeRegex . MatchString ( element ) {
2019-07-07 16:34:56 +00:00
if seenDuration {
return false // code after duration
}
continue
}
2023-06-01 14:29:47 +00:00
if durationRegex . MatchString ( element ) {
2019-07-07 16:34:56 +00:00
seenDuration = true
}
}
return seenDuration
}
2016-12-29 20:02:06 +00:00
type authReq struct {
2023-07-22 03:32:07 +00:00
r resolver . Resolver
annotationConfig parser . Annotation
2016-12-29 20:02:06 +00:00
}
// NewParser creates a new authentication request annotation parser
2017-11-08 20:58:57 +00:00
func NewParser ( r resolver . Resolver ) parser . IngressAnnotation {
2023-07-22 03:32:07 +00:00
return authReq {
r : r ,
annotationConfig : authReqAnnotations ,
}
2016-12-29 20:02:06 +00:00
}
2016-08-19 14:51:40 +00:00
// ParseAnnotations parses the annotations contained in the ingress
2017-11-07 16:36:51 +00:00
// rule used to use an Config URL as source for authentication
2023-08-31 07:36:48 +00:00
//
//nolint:gocyclo // Ignore function complexity error
2019-06-09 22:49:59 +00:00
func ( a authReq ) Parse ( ing * networking . Ingress ) ( interface { } , error ) {
2018-01-28 00:32:08 +00:00
// Required Parameters
2023-07-22 03:32:07 +00:00
urlString , err := parser . GetStringAnnotation ( authReqURLAnnotation , ing , a . annotationConfig . Annotations )
2016-08-19 14:51:40 +00:00
if err != nil {
2016-12-29 20:02:06 +00:00
return nil , err
2016-08-19 14:51:40 +00:00
}
2020-02-05 02:06:07 +00:00
authURL , err := parser . StringToURL ( urlString )
if err != nil {
2023-08-31 07:36:48 +00:00
return nil , ing_errors . LocationDeniedError { Reason : fmt . Errorf ( "could not parse auth-url annotation: %v" , err ) }
2016-08-19 14:51:40 +00:00
}
2023-07-22 03:32:07 +00:00
authMethod , err := parser . GetStringAnnotation ( authReqMethodAnnotation , ing , a . annotationConfig . Annotations )
if err != nil {
if ing_errors . IsValidationError ( err ) {
return nil , ing_errors . NewLocationDenied ( "invalid HTTP method" )
}
2016-08-19 14:51:40 +00:00
}
2018-01-28 00:32:08 +00:00
// Optional Parameters
2023-07-22 03:32:07 +00:00
signIn , err := parser . GetStringAnnotation ( authReqSigninAnnotation , ing , a . annotationConfig . Annotations )
2018-10-29 21:34:44 +00:00
if err != nil {
2023-07-22 03:32:07 +00:00
if ing_errors . IsValidationError ( err ) {
klog . Warningf ( "%s value is invalid: %s" , authReqSigninAnnotation , err )
}
2020-09-27 20:32:40 +00:00
klog . V ( 3 ) . InfoS ( "auth-signin annotation is undefined and will not be set" )
2018-10-29 21:34:44 +00:00
}
2023-07-22 03:32:07 +00:00
signInRedirectParam , err := parser . GetStringAnnotation ( authReqSigninRedirParamAnnotation , ing , a . annotationConfig . Annotations )
2020-08-18 09:03:38 +00:00
if err != nil {
2023-07-22 03:32:07 +00:00
if ing_errors . IsValidationError ( err ) {
klog . Warningf ( "%s value is invalid: %s" , authReqSigninRedirParamAnnotation , err )
}
2020-08-18 09:03:38 +00:00
klog . V ( 3 ) . Infof ( "auth-signin-redirect-param annotation is undefined and will not be set" )
}
2023-07-22 03:32:07 +00:00
authSnippet , err := parser . GetStringAnnotation ( authReqSnippetAnnotation , ing , a . annotationConfig . Annotations )
2018-10-29 21:34:44 +00:00
if err != nil {
2020-09-27 20:32:40 +00:00
klog . V ( 3 ) . InfoS ( "auth-snippet annotation is undefined and will not be set" )
2018-10-29 21:34:44 +00:00
}
2018-01-28 00:32:08 +00:00
2023-07-22 03:32:07 +00:00
authCacheKey , err := parser . GetStringAnnotation ( authReqCacheKeyAnnotation , ing , a . annotationConfig . Annotations )
2019-07-07 16:34:56 +00:00
if err != nil {
2023-07-22 03:32:07 +00:00
if ing_errors . IsValidationError ( err ) {
klog . Warningf ( "%s value is invalid: %s" , authReqCacheKeyAnnotation , err )
}
2020-09-27 20:32:40 +00:00
klog . V ( 3 ) . InfoS ( "auth-cache-key annotation is undefined and will not be set" )
2019-07-07 16:34:56 +00:00
}
2023-07-22 03:32:07 +00:00
keepaliveConnections , err := parser . GetIntAnnotation ( authReqKeepaliveAnnotation , ing , a . annotationConfig . Annotations )
2022-04-09 03:22:04 +00:00
if err != nil {
klog . V ( 3 ) . InfoS ( "auth-keepalive annotation is undefined and will be set to its default value" )
keepaliveConnections = defaultKeepaliveConnections
}
switch {
case keepaliveConnections < 0 :
klog . Warningf ( "auth-keepalive annotation (%s) contains a negative value, setting auth-keepalive to 0" , authURL . Host )
keepaliveConnections = 0
case keepaliveConnections > 0 :
// NOTE: upstream block cannot reference a variable in the server directive
if strings . IndexByte ( authURL . Host , '$' ) != - 1 {
klog . Warningf ( "auth-url annotation (%s) contains $ in the host:port part, setting auth-keepalive to 0" , authURL . Host )
keepaliveConnections = 0
}
}
2023-08-07 13:16:32 +00:00
keepaliveShareVars , err := parser . GetBoolAnnotation ( authReqKeepaliveShareVarsAnnotation , ing , a . annotationConfig . Annotations )
if err != nil {
klog . V ( 3 ) . InfoS ( "auth-keepalive-share-vars annotation is undefined and will be set to its default value" )
keepaliveShareVars = defaultKeepaliveShareVars
}
2023-07-22 03:32:07 +00:00
keepaliveRequests , err := parser . GetIntAnnotation ( authReqKeepaliveRequestsAnnotation , ing , a . annotationConfig . Annotations )
2022-04-09 03:22:04 +00:00
if err != nil {
2023-07-22 03:32:07 +00:00
klog . V ( 3 ) . InfoS ( "auth-keepalive-requests annotation is undefined or invalid and will be set to its default value" )
2022-04-09 03:22:04 +00:00
keepaliveRequests = defaultKeepaliveRequests
}
if keepaliveRequests <= 0 {
klog . Warningf ( "auth-keepalive-requests annotation (%s) should be greater than zero, setting auth-keepalive to 0" , authURL . Host )
keepaliveConnections = 0
}
2023-07-22 03:32:07 +00:00
keepaliveTimeout , err := parser . GetIntAnnotation ( authReqKeepaliveTimeout , ing , a . annotationConfig . Annotations )
2022-04-09 03:22:04 +00:00
if err != nil {
klog . V ( 3 ) . InfoS ( "auth-keepalive-timeout annotation is undefined and will be set to its default value" )
keepaliveTimeout = defaultKeepaliveTimeout
}
if keepaliveTimeout <= 0 {
klog . Warningf ( "auth-keepalive-timeout annotation (%s) should be greater than zero, setting auth-keepalive 0" , authURL . Host )
keepaliveConnections = 0
}
2023-07-22 03:32:07 +00:00
durstr , err := parser . GetStringAnnotation ( authReqCacheDuration , ing , a . annotationConfig . Annotations )
if err != nil && ing_errors . IsValidationError ( err ) {
return nil , fmt . Errorf ( "%s contains invalid value" , authReqCacheDuration )
}
2019-07-07 16:34:56 +00:00
authCacheDuration , err := ParseStringToCacheDurations ( durstr )
if err != nil {
return nil , err
}
2018-01-28 00:32:08 +00:00
responseHeaders := [ ] string { }
2023-07-22 03:32:07 +00:00
hstr , err := parser . GetStringAnnotation ( authReqResponseHeadersAnnotation , ing , a . annotationConfig . Annotations )
if err != nil && ing_errors . IsValidationError ( err ) {
return nil , ing_errors . NewLocationDenied ( "validation error" )
}
2023-08-31 07:36:48 +00:00
if hstr != "" {
2017-02-04 00:43:15 +00:00
harr := strings . Split ( hstr , "," )
for _ , header := range harr {
2017-08-23 18:40:57 +00:00
header = strings . TrimSpace ( header )
2024-03-07 10:39:53 +00:00
if header != "" {
2018-11-27 16:12:17 +00:00
if ! ValidHeader ( header ) {
2017-02-04 00:43:15 +00:00
return nil , ing_errors . NewLocationDenied ( "invalid headers list" )
}
2018-01-28 00:32:08 +00:00
responseHeaders = append ( responseHeaders , header )
2017-02-04 00:43:15 +00:00
}
}
}
2023-07-22 03:32:07 +00:00
proxySetHeaderMap , err := parser . GetStringAnnotation ( authReqProxySetHeadersAnnotation , ing , a . annotationConfig . Annotations )
if err != nil {
klog . V ( 3 ) . InfoS ( "auth-set-proxy-headers annotation is undefined and will not be set" , "err" , err )
}
cns , _ , err := cache . SplitMetaNamespaceKey ( proxySetHeaderMap )
2019-09-24 14:53:23 +00:00
if err != nil {
2023-08-31 07:36:48 +00:00
return nil , ing_errors . LocationDeniedError {
2023-07-22 03:32:07 +00:00
Reason : fmt . Errorf ( "error reading configmap name %s from annotation: %w" , proxySetHeaderMap , err ) ,
}
}
if cns == "" {
cns = ing . Namespace
}
secCfg := a . r . GetSecurityConfiguration ( )
// We don't accept different namespaces for secrets.
if ! secCfg . AllowCrossNamespaceResources && cns != ing . Namespace {
2023-08-31 07:36:48 +00:00
return nil , ing_errors . LocationDeniedError {
2023-07-22 03:32:07 +00:00
Reason : fmt . Errorf ( "cross namespace usage of secrets is not allowed" ) ,
}
2019-09-24 14:53:23 +00:00
}
var proxySetHeaders map [ string ] string
if proxySetHeaderMap != "" {
proxySetHeadersMapContents , err := a . r . GetConfigMap ( proxySetHeaderMap )
if err != nil {
return nil , ing_errors . NewLocationDenied ( fmt . Sprintf ( "unable to find configMap %q" , proxySetHeaderMap ) )
}
2020-02-11 13:30:14 +00:00
for header := range proxySetHeadersMapContents . Data {
if ! ValidHeader ( header ) {
2019-09-24 14:53:23 +00:00
return nil , ing_errors . NewLocationDenied ( "invalid proxy-set-headers in configmap" )
}
}
proxySetHeaders = proxySetHeadersMapContents . Data
}
2023-07-22 03:32:07 +00:00
requestRedirect , err := parser . GetStringAnnotation ( authReqRequestRedirectAnnotation , ing , a . annotationConfig . Annotations )
if err != nil && ing_errors . IsValidationError ( err ) {
return nil , fmt . Errorf ( "%s is invalid: %w" , authReqRequestRedirectAnnotation , err )
}
2018-01-28 00:32:08 +00:00
2023-07-22 03:32:07 +00:00
alwaysSetCookie , err := parser . GetBoolAnnotation ( authReqAlwaysSetCookieAnnotation , ing , a . annotationConfig . Annotations )
if err != nil && ing_errors . IsValidationError ( err ) {
return nil , fmt . Errorf ( "%s is invalid: %w" , authReqAlwaysSetCookieAnnotation , err )
}
2022-05-19 22:27:53 +00:00
2017-11-07 16:36:51 +00:00
return & Config {
2020-08-18 09:03:38 +00:00
URL : urlString ,
Host : authURL . Hostname ( ) ,
SigninURL : signIn ,
SigninURLRedirectParam : signInRedirectParam ,
Method : authMethod ,
ResponseHeaders : responseHeaders ,
RequestRedirect : requestRedirect ,
AuthSnippet : authSnippet ,
AuthCacheKey : authCacheKey ,
AuthCacheDuration : authCacheDuration ,
2022-04-09 03:22:04 +00:00
KeepaliveConnections : keepaliveConnections ,
2023-08-07 13:16:32 +00:00
KeepaliveShareVars : keepaliveShareVars ,
2022-04-09 03:22:04 +00:00
KeepaliveRequests : keepaliveRequests ,
KeepaliveTimeout : keepaliveTimeout ,
2020-08-18 09:03:38 +00:00
ProxySetHeaders : proxySetHeaders ,
2022-05-19 22:27:53 +00:00
AlwaysSetCookie : alwaysSetCookie ,
2016-08-19 14:51:40 +00:00
} , nil
}
2018-11-27 16:12:17 +00:00
2019-07-07 16:34:56 +00:00
// ParseStringToCacheDurations parses and validates the provided string
// into a list of cache durations.
// It will always return at least one duration (the default duration)
func ParseStringToCacheDurations ( input string ) ( [ ] string , error ) {
authCacheDuration := [ ] string { }
2023-08-31 07:36:48 +00:00
if input != "" {
2019-07-07 16:34:56 +00:00
arr := strings . Split ( input , "," )
for _ , duration := range arr {
duration = strings . TrimSpace ( duration )
2024-03-07 10:39:53 +00:00
if duration != "" {
2019-07-07 16:34:56 +00:00
if ! ValidCacheDuration ( duration ) {
authCacheDuration = [ ] string { DefaultCacheDuration }
return authCacheDuration , ing_errors . NewLocationDenied ( fmt . Sprintf ( "invalid cache duration: %s" , duration ) )
}
authCacheDuration = append ( authCacheDuration , duration )
}
}
}
if len ( authCacheDuration ) == 0 {
authCacheDuration = append ( authCacheDuration , DefaultCacheDuration )
}
return authCacheDuration , nil
}
2023-07-22 03:32:07 +00:00
func ( a authReq ) GetDocumentation ( ) parser . AnnotationFields {
return a . annotationConfig . Annotations
}
func ( a authReq ) Validate ( anns map [ string ] string ) error {
maxrisk := parser . StringRiskToRisk ( a . r . GetSecurityConfiguration ( ) . AnnotationsRiskLevel )
return parser . CheckAnnotationRisk ( anns , maxrisk , authReqAnnotations . Annotations )
}