From 2a409215d3005f0a0efc3313e23957a118b2d05f Mon Sep 17 00:00:00 2001 From: Jens L Date: Thu, 29 Apr 2021 18:17:10 +0200 Subject: [PATCH] outpost: forwardAuth mode (#790) --- authentik/providers/proxy/api.py | 2 + .../0011_proxyprovider_forward_auth_mode.py | 35 +++ authentik/providers/proxy/models.py | 10 +- outpost/Makefile | 4 +- outpost/pkg/proxy/api_bundle.go | 29 ++- outpost/pkg/proxy/proxy.go | 22 +- swagger.yaml | 14 +- web/src/locales/en.po | 56 +++-- web/src/locales/pseudo-LOCALE.po | 56 +++-- .../providers/proxy/ProxyProviderForm.ts | 57 +++-- website/docs/outposts/proxy.md | 16 -- website/docs/outposts/proxy.mdx | 229 ++++++++++++++++++ 12 files changed, 433 insertions(+), 97 deletions(-) create mode 100644 authentik/providers/proxy/migrations/0011_proxyprovider_forward_auth_mode.py delete mode 100644 website/docs/outposts/proxy.md create mode 100644 website/docs/outposts/proxy.mdx diff --git a/authentik/providers/proxy/api.py b/authentik/providers/proxy/api.py index cd2e54cff..cac707448 100644 --- a/authentik/providers/proxy/api.py +++ b/authentik/providers/proxy/api.py @@ -52,6 +52,7 @@ class ProxyProviderSerializer(ProviderSerializer): "basic_auth_enabled", "basic_auth_password_attribute", "basic_auth_user_attribute", + "forward_auth_mode", ] @@ -86,6 +87,7 @@ class ProxyOutpostConfigSerializer(ModelSerializer): "basic_auth_enabled", "basic_auth_password_attribute", "basic_auth_user_attribute", + "forward_auth_mode", ] @swagger_serializer_method(serializer_or_field=OpenIDConnectConfigurationSerializer) diff --git a/authentik/providers/proxy/migrations/0011_proxyprovider_forward_auth_mode.py b/authentik/providers/proxy/migrations/0011_proxyprovider_forward_auth_mode.py new file mode 100644 index 000000000..b9be9af13 --- /dev/null +++ b/authentik/providers/proxy/migrations/0011_proxyprovider_forward_auth_mode.py @@ -0,0 +1,35 @@ +# Generated by Django 3.2 on 2021-04-27 18:47 + +from django.db import migrations, models + +import authentik.lib.models + + +class Migration(migrations.Migration): + + dependencies = [ + ("authentik_providers_proxy", "0010_auto_20201214_0942"), + ] + + operations = [ + migrations.AddField( + model_name="proxyprovider", + name="forward_auth_mode", + field=models.BooleanField( + default=False, + help_text="Enable support for forwardAuth in traefik and nginx auth_request. Exclusive with internal_host.", + ), + ), + migrations.AlterField( + model_name="proxyprovider", + name="internal_host", + field=models.TextField( + blank=True, + validators=[ + authentik.lib.models.DomainlessURLValidator( + schemes=("http", "https") + ) + ], + ), + ), + ] diff --git a/authentik/providers/proxy/models.py b/authentik/providers/proxy/models.py index 3cba47c17..ed4df13ea 100644 --- a/authentik/providers/proxy/models.py +++ b/authentik/providers/proxy/models.py @@ -42,7 +42,8 @@ class ProxyProvider(OutpostModel, OAuth2Provider): Protocols by using a Reverse-Proxy.""" internal_host = models.TextField( - validators=[DomainlessURLValidator(schemes=("http", "https"))] + validators=[DomainlessURLValidator(schemes=("http", "https"))], + blank=True, ) external_host = models.TextField( validators=[DomainlessURLValidator(schemes=("http", "https"))] @@ -52,6 +53,13 @@ class ProxyProvider(OutpostModel, OAuth2Provider): help_text=_("Validate SSL Certificates of upstream servers"), verbose_name=_("Internal host SSL Validation"), ) + forward_auth_mode = models.BooleanField( + default=False, + help_text=_( + "Enable support for forwardAuth in traefik and nginx auth_request. Exclusive with " + "internal_host." + ), + ) skip_path_regex = models.TextField( default="", diff --git a/outpost/Makefile b/outpost/Makefile index 5b24cb1c9..d4eaa5f5c 100644 --- a/outpost/Makefile +++ b/outpost/Makefile @@ -1,4 +1,4 @@ -all: clean generate build +all: clean generate generate: go get -u github.com/go-swagger/go-swagger/cmd/swagger @@ -11,5 +11,3 @@ clean: go mod tidy go clean . -build: - go build -v . diff --git a/outpost/pkg/proxy/api_bundle.go b/outpost/pkg/proxy/api_bundle.go index 993659310..4262b8a99 100644 --- a/outpost/pkg/proxy/api_bundle.go +++ b/outpost/pkg/proxy/api_bundle.go @@ -31,6 +31,10 @@ type providerBundle struct { log *log.Entry } +func intToPointer(i int) *int { + return &i +} + func (pb *providerBundle) prepareOpts(provider *models.ProxyOutpostConfig) *options.Options { externalHost, err := url.Parse(*provider.ExternalHost) if err != nil { @@ -61,13 +65,24 @@ func (pb *providerBundle) prepareOpts(provider *models.ProxyOutpostConfig) *opti providerOpts.SkipAuthRegex = skipRegexes } - providerOpts.UpstreamServers = []options.Upstream{ - { - ID: "default", - URI: *provider.InternalHost, - Path: "/", - InsecureSkipTLSVerify: provider.InternalHostSslValidation, - }, + if provider.ForwardAuthMode { + providerOpts.UpstreamServers = []options.Upstream{ + { + ID: "static", + Static: true, + StaticCode: intToPointer(202), + Path: "/", + }, + } + } else { + providerOpts.UpstreamServers = []options.Upstream{ + { + ID: "default", + URI: provider.InternalHost, + Path: "/", + InsecureSkipTLSVerify: provider.InternalHostSslValidation, + }, + } } if provider.Certificate != nil { diff --git a/outpost/pkg/proxy/proxy.go b/outpost/pkg/proxy/proxy.go index 44643c959..a380f486c 100644 --- a/outpost/pkg/proxy/proxy.go +++ b/outpost/pkg/proxy/proxy.go @@ -63,6 +63,7 @@ type OAuthProxy struct { AuthOnlyPath string UserInfoPath string + forwardAuthMode bool redirectURL *url.URL // the url to receive requests at whitelistDomains []string provider providers.Provider @@ -132,6 +133,7 @@ func NewOAuthProxy(opts *options.Options, provider *models.ProxyOutpostConfig) ( CookieRefresh: opts.Cookie.Refresh, CookieSameSite: opts.Cookie.SameSite, + forwardAuthMode: provider.ForwardAuthMode, RobotsPath: "/robots.txt", SignInPath: fmt.Sprintf("%s/sign_in", opts.ProxyPrefix), SignOutPath: fmt.Sprintf("%s/sign_out", opts.ProxyPrefix), @@ -335,12 +337,29 @@ func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request) { func (p *OAuthProxy) AuthenticateOnly(rw http.ResponseWriter, req *http.Request) { session, err := p.getAuthenticatedSession(rw, req) if err != nil { + if p.forwardAuthMode { + if _, ok := req.URL.Query()["nginx"]; ok { + rw.WriteHeader(401) + return + } + if _, ok := req.URL.Query()["traefik"]; ok { + host := getHost(req) + http.Redirect(rw, req, fmt.Sprintf("//%s%s", host, p.OAuthStartPath), http.StatusTemporaryRedirect) + return + } + } http.Error(rw, "unauthorized request", http.StatusUnauthorized) return } - // we are authenticated p.addHeadersForProxying(rw, req, session) + if p.forwardAuthMode { + for headerKey, headers := range req.Header { + for _, value := range headers { + rw.Header().Set(headerKey, value) + } + } + } rw.WriteHeader(http.StatusAccepted) } @@ -435,7 +454,6 @@ func (p *OAuthProxy) addHeadersForProxying(rw http.ResponseWriter, req *http.Req authVal := b64.StdEncoding.EncodeToString([]byte(username + ":" + password)) req.Header["Authorization"] = []string{fmt.Sprintf("Basic %s", authVal)} } - rw.Header().Set("GAP-Auth", session.PreferredUsername) // Check if user has additional headers set that we should sent if additionalHeaders, ok := userAttributes["additionalHeaders"].(map[string]string); ok { if additionalHeaders == nil { diff --git a/swagger.yaml b/swagger.yaml index b56f071ce..0269141a2 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -15764,7 +15764,6 @@ definitions: ProxyOutpostConfig: required: - name - - internal_host - external_host type: object properties: @@ -15779,7 +15778,6 @@ definitions: internal_host: title: Internal host type: string - minLength: 1 external_host: title: External host type: string @@ -15828,6 +15826,11 @@ definitions: description: User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used. type: string + forward_auth_mode: + title: Forward auth mode + description: Enable support for forwardAuth in traefik and nginx auth_request. + Exclusive with internal_host. + type: boolean ServiceConnection: required: - name @@ -16737,7 +16740,6 @@ definitions: required: - name - authorization_flow - - internal_host - external_host type: object properties: @@ -16783,7 +16785,6 @@ definitions: internal_host: title: Internal host type: string - minLength: 1 external_host: title: External host type: string @@ -16817,6 +16818,11 @@ definitions: description: User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used. type: string + forward_auth_mode: + title: Forward auth mode + description: Enable support for forwardAuth in traefik and nginx auth_request. + Exclusive with internal_host. + type: boolean SAMLProvider: required: - name diff --git a/web/src/locales/en.po b/web/src/locales/en.po index cd4f560a5..bfe9b0dd6 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -117,7 +117,7 @@ msgid "Additional user DN, prepended to the Base DN." msgstr "Additional user DN, prepended to the Base DN." #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:132 -#: src/pages/providers/proxy/ProxyProviderForm.ts:130 +#: src/pages/providers/proxy/ProxyProviderForm.ts:153 #: src/pages/providers/saml/SAMLProviderForm.ts:117 #: src/pages/sources/saml/SAMLSourceForm.ts:134 msgid "Advanced protocol settings" @@ -305,7 +305,7 @@ msgid "Authorization URL" msgstr "Authorization URL" #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:62 -#: src/pages/providers/proxy/ProxyProviderForm.ts:80 +#: src/pages/providers/proxy/ProxyProviderForm.ts:104 #: src/pages/providers/saml/SAMLProviderForm.ts:59 #: src/pages/providers/saml/SAMLProviderImportForm.ts:44 msgid "Authorization flow" @@ -433,7 +433,7 @@ msgid "Case insensitive matching" msgstr "Case insensitive matching" #: src/pages/crypto/CertificateKeyPairForm.ts:51 -#: src/pages/providers/proxy/ProxyProviderForm.ts:134 +#: src/pages/providers/proxy/ProxyProviderForm.ts:157 msgid "Certificate" msgstr "Certificate" @@ -1123,6 +1123,14 @@ msgstr "Enable Static Tokens" msgid "Enable TOTP" msgstr "Enable TOTP" +#: src/pages/providers/proxy/ProxyProviderForm.ts:140 +msgid "Enable forward-auth mode" +msgstr "Enable forward-auth mode" + +#: src/pages/providers/proxy/ProxyProviderForm.ts:144 +msgid "Enable this if you don't want to use this provider as a proxy, and want to use it with Traefik's forwardAuth or nginx's auth_request." +msgstr "Enable this if you don't want to use this provider as a proxy, and want to use it with Traefik's forwardAuth or nginx's auth_request." + #: src/pages/policies/BoundPoliciesList.ts:41 #: src/pages/policies/PolicyBindingForm.ts:199 #: src/pages/sources/ldap/LDAPSourceForm.ts:69 @@ -1281,7 +1289,7 @@ msgstr "External Applications which use authentik as Identity-Provider, utilizin msgid "External Host" msgstr "External Host" -#: src/pages/providers/proxy/ProxyProviderForm.ts:119 +#: src/pages/providers/proxy/ProxyProviderForm.ts:127 msgid "External host" msgstr "External host" @@ -1376,7 +1384,7 @@ msgid "Flow used by an authenticated user to configure this Stage. If empty, use msgstr "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage." #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:76 -#: src/pages/providers/proxy/ProxyProviderForm.ts:94 +#: src/pages/providers/proxy/ProxyProviderForm.ts:118 #: src/pages/providers/saml/SAMLProviderForm.ts:73 #: src/pages/providers/saml/SAMLProviderImportForm.ts:57 msgid "Flow used when authorizing this provider." @@ -1474,11 +1482,11 @@ msgstr "Groups" msgid "HS256 (Symmetric Encryption)" msgstr "HS256 (Symmetric Encryption)" -#: src/pages/providers/proxy/ProxyProviderForm.ts:64 +#: src/pages/providers/proxy/ProxyProviderForm.ts:66 msgid "HTTP-Basic Password Key" msgstr "HTTP-Basic Password Key" -#: src/pages/providers/proxy/ProxyProviderForm.ts:58 +#: src/pages/providers/proxy/ProxyProviderForm.ts:60 msgid "HTTP-Basic Username Key" msgstr "HTTP-Basic Username Key" @@ -1587,11 +1595,11 @@ msgstr "Internal Host" msgid "Internal application name, used in URLs." msgstr "Internal application name, used in URLs." -#: src/pages/providers/proxy/ProxyProviderForm.ts:103 +#: src/pages/providers/proxy/ProxyProviderForm.ts:78 msgid "Internal host" msgstr "Internal host" -#: src/pages/providers/proxy/ProxyProviderForm.ts:113 +#: src/pages/providers/proxy/ProxyProviderForm.ts:88 msgid "Internal host SSL Validation" msgstr "Internal host SSL Validation" @@ -1728,8 +1736,8 @@ msgstr "Loading" #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:74 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:185 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:203 -#: src/pages/providers/proxy/ProxyProviderForm.ts:92 -#: src/pages/providers/proxy/ProxyProviderForm.ts:145 +#: src/pages/providers/proxy/ProxyProviderForm.ts:116 +#: src/pages/providers/proxy/ProxyProviderForm.ts:168 #: src/pages/providers/saml/SAMLProviderForm.ts:71 #: src/pages/providers/saml/SAMLProviderForm.ts:133 #: src/pages/providers/saml/SAMLProviderForm.ts:149 @@ -1899,7 +1907,7 @@ msgstr "Monitor" #: src/pages/providers/ProviderListPage.ts:52 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:56 #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:73 -#: src/pages/providers/proxy/ProxyProviderForm.ts:74 +#: src/pages/providers/proxy/ProxyProviderForm.ts:98 #: src/pages/providers/proxy/ProxyProviderViewPage.ts:64 #: src/pages/providers/saml/SAMLProviderForm.ts:53 #: src/pages/providers/saml/SAMLProviderImportForm.ts:38 @@ -2400,7 +2408,7 @@ msgid "Property mappings used to user creation." msgstr "Property mappings used to user creation." #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:81 -#: src/pages/providers/proxy/ProxyProviderForm.ts:99 +#: src/pages/providers/proxy/ProxyProviderForm.ts:123 #: src/pages/providers/saml/SAMLProviderForm.ts:78 #: src/pages/sources/oauth/OAuthSourceForm.ts:122 #: src/pages/sources/saml/SAMLSourceForm.ts:76 @@ -2531,7 +2539,7 @@ msgstr "Refresh Code" msgid "Register device" msgstr "Register device" -#: src/pages/providers/proxy/ProxyProviderForm.ts:153 +#: src/pages/providers/proxy/ProxyProviderForm.ts:176 msgid "Regular expressions for which authentication is not required. Each new line is interpreted as a new Regular Expression." msgstr "Regular expressions for which authentication is not required. Each new line is interpreted as a new Regular Expression." @@ -2774,11 +2782,11 @@ msgstr "Session not valid on or after current time + this value (Format: hours=1 msgid "Session valid not on or after" msgstr "Session valid not on or after" -#: src/pages/providers/proxy/ProxyProviderForm.ts:163 +#: src/pages/providers/proxy/ProxyProviderForm.ts:186 msgid "Set HTTP-Basic Authentication" msgstr "Set HTTP-Basic Authentication" -#: src/pages/providers/proxy/ProxyProviderForm.ts:166 +#: src/pages/providers/proxy/ProxyProviderForm.ts:189 msgid "Set a custom HTTP-Basic Authentication header based on values from authentik." msgstr "Set a custom HTTP-Basic Authentication header based on values from authentik." @@ -2828,7 +2836,7 @@ msgstr "Signing keypair" msgid "Single Prompts that can be used for Prompt Stages." msgstr "Single Prompts that can be used for Prompt Stages." -#: src/pages/providers/proxy/ProxyProviderForm.ts:150 +#: src/pages/providers/proxy/ProxyProviderForm.ts:173 msgid "Skip path regex" msgstr "Skip path regex" @@ -3040,7 +3048,7 @@ msgid "Successfully created prompt." msgstr "Successfully created prompt." #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:49 -#: src/pages/providers/proxy/ProxyProviderForm.ts:49 +#: src/pages/providers/proxy/ProxyProviderForm.ts:51 #: src/pages/providers/saml/SAMLProviderForm.ts:46 msgid "Successfully created provider." msgstr "Successfully created provider." @@ -3176,7 +3184,7 @@ msgid "Successfully updated prompt." msgstr "Successfully updated prompt." #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:46 -#: src/pages/providers/proxy/ProxyProviderForm.ts:46 +#: src/pages/providers/proxy/ProxyProviderForm.ts:48 #: src/pages/providers/saml/SAMLProviderForm.ts:43 msgid "Successfully updated provider." msgstr "Successfully updated provider." @@ -3325,7 +3333,7 @@ msgstr "Text: Simple Text input" msgid "The URL \"{0}\" was not found." msgstr "The URL \"{0}\" was not found." -#: src/pages/providers/proxy/ProxyProviderForm.ts:123 +#: src/pages/providers/proxy/ProxyProviderForm.ts:131 msgid "The external URL you'll access the outpost at." msgstr "The external URL you'll access the outpost at." @@ -3635,7 +3643,7 @@ msgstr "Update details" msgid "Update {0}" msgstr "Update {0}" -#: src/pages/providers/proxy/ProxyProviderForm.ts:107 +#: src/pages/providers/proxy/ProxyProviderForm.ts:82 msgid "Upstream host that the requests are forwarded to." msgstr "Upstream host that the requests are forwarded to." @@ -3721,11 +3729,11 @@ msgstr "User's avatar" msgid "User's display name." msgstr "User's display name." -#: src/pages/providers/proxy/ProxyProviderForm.ts:67 +#: src/pages/providers/proxy/ProxyProviderForm.ts:69 msgid "User/Group Attribute used for the password part of the HTTP-Basic Header." msgstr "User/Group Attribute used for the password part of the HTTP-Basic Header." -#: src/pages/providers/proxy/ProxyProviderForm.ts:61 +#: src/pages/providers/proxy/ProxyProviderForm.ts:63 msgid "User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used." msgstr "User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used." @@ -3766,7 +3774,7 @@ msgstr "Using source" msgid "Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows." msgstr "Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows." -#: src/pages/providers/proxy/ProxyProviderForm.ts:116 +#: src/pages/providers/proxy/ProxyProviderForm.ts:91 msgid "Validate SSL Certificates of upstream servers." msgstr "Validate SSL Certificates of upstream servers." diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index a8822e9c8..25835c216 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -117,7 +117,7 @@ msgid "Additional user DN, prepended to the Base DN." msgstr "" #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:132 -#: src/pages/providers/proxy/ProxyProviderForm.ts:130 +#: src/pages/providers/proxy/ProxyProviderForm.ts:153 #: src/pages/providers/saml/SAMLProviderForm.ts:117 #: src/pages/sources/saml/SAMLSourceForm.ts:134 msgid "Advanced protocol settings" @@ -301,7 +301,7 @@ msgid "Authorization URL" msgstr "" #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:62 -#: src/pages/providers/proxy/ProxyProviderForm.ts:80 +#: src/pages/providers/proxy/ProxyProviderForm.ts:104 #: src/pages/providers/saml/SAMLProviderForm.ts:59 #: src/pages/providers/saml/SAMLProviderImportForm.ts:44 msgid "Authorization flow" @@ -429,7 +429,7 @@ msgid "Case insensitive matching" msgstr "" #: src/pages/crypto/CertificateKeyPairForm.ts:51 -#: src/pages/providers/proxy/ProxyProviderForm.ts:134 +#: src/pages/providers/proxy/ProxyProviderForm.ts:157 msgid "Certificate" msgstr "" @@ -1115,6 +1115,14 @@ msgstr "" msgid "Enable TOTP" msgstr "" +#: src/pages/providers/proxy/ProxyProviderForm.ts:140 +msgid "Enable forward-auth mode" +msgstr "" + +#: src/pages/providers/proxy/ProxyProviderForm.ts:144 +msgid "Enable this if you don't want to use this provider as a proxy, and want to use it with Traefik's forwardAuth or nginx's auth_request." +msgstr "" + #: src/pages/policies/BoundPoliciesList.ts:41 #: src/pages/policies/PolicyBindingForm.ts:199 #: src/pages/sources/ldap/LDAPSourceForm.ts:69 @@ -1273,7 +1281,7 @@ msgstr "" msgid "External Host" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:119 +#: src/pages/providers/proxy/ProxyProviderForm.ts:127 msgid "External host" msgstr "" @@ -1368,7 +1376,7 @@ msgid "Flow used by an authenticated user to configure this Stage. If empty, use msgstr "" #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:76 -#: src/pages/providers/proxy/ProxyProviderForm.ts:94 +#: src/pages/providers/proxy/ProxyProviderForm.ts:118 #: src/pages/providers/saml/SAMLProviderForm.ts:73 #: src/pages/providers/saml/SAMLProviderImportForm.ts:57 msgid "Flow used when authorizing this provider." @@ -1466,11 +1474,11 @@ msgstr "" msgid "HS256 (Symmetric Encryption)" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:64 +#: src/pages/providers/proxy/ProxyProviderForm.ts:66 msgid "HTTP-Basic Password Key" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:58 +#: src/pages/providers/proxy/ProxyProviderForm.ts:60 msgid "HTTP-Basic Username Key" msgstr "" @@ -1579,11 +1587,11 @@ msgstr "" msgid "Internal application name, used in URLs." msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:103 +#: src/pages/providers/proxy/ProxyProviderForm.ts:78 msgid "Internal host" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:113 +#: src/pages/providers/proxy/ProxyProviderForm.ts:88 msgid "Internal host SSL Validation" msgstr "" @@ -1720,8 +1728,8 @@ msgstr "" #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:74 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:185 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:203 -#: src/pages/providers/proxy/ProxyProviderForm.ts:92 -#: src/pages/providers/proxy/ProxyProviderForm.ts:145 +#: src/pages/providers/proxy/ProxyProviderForm.ts:116 +#: src/pages/providers/proxy/ProxyProviderForm.ts:168 #: src/pages/providers/saml/SAMLProviderForm.ts:71 #: src/pages/providers/saml/SAMLProviderForm.ts:133 #: src/pages/providers/saml/SAMLProviderForm.ts:149 @@ -1891,7 +1899,7 @@ msgstr "" #: src/pages/providers/ProviderListPage.ts:52 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:56 #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:73 -#: src/pages/providers/proxy/ProxyProviderForm.ts:74 +#: src/pages/providers/proxy/ProxyProviderForm.ts:98 #: src/pages/providers/proxy/ProxyProviderViewPage.ts:64 #: src/pages/providers/saml/SAMLProviderForm.ts:53 #: src/pages/providers/saml/SAMLProviderImportForm.ts:38 @@ -2392,7 +2400,7 @@ msgid "Property mappings used to user creation." msgstr "" #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:81 -#: src/pages/providers/proxy/ProxyProviderForm.ts:99 +#: src/pages/providers/proxy/ProxyProviderForm.ts:123 #: src/pages/providers/saml/SAMLProviderForm.ts:78 #: src/pages/sources/oauth/OAuthSourceForm.ts:122 #: src/pages/sources/saml/SAMLSourceForm.ts:76 @@ -2523,7 +2531,7 @@ msgstr "" msgid "Register device" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:153 +#: src/pages/providers/proxy/ProxyProviderForm.ts:176 msgid "Regular expressions for which authentication is not required. Each new line is interpreted as a new Regular Expression." msgstr "" @@ -2766,11 +2774,11 @@ msgstr "" msgid "Session valid not on or after" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:163 +#: src/pages/providers/proxy/ProxyProviderForm.ts:186 msgid "Set HTTP-Basic Authentication" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:166 +#: src/pages/providers/proxy/ProxyProviderForm.ts:189 msgid "Set a custom HTTP-Basic Authentication header based on values from authentik." msgstr "" @@ -2820,7 +2828,7 @@ msgstr "" msgid "Single Prompts that can be used for Prompt Stages." msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:150 +#: src/pages/providers/proxy/ProxyProviderForm.ts:173 msgid "Skip path regex" msgstr "" @@ -3032,7 +3040,7 @@ msgid "Successfully created prompt." msgstr "" #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:49 -#: src/pages/providers/proxy/ProxyProviderForm.ts:49 +#: src/pages/providers/proxy/ProxyProviderForm.ts:51 #: src/pages/providers/saml/SAMLProviderForm.ts:46 msgid "Successfully created provider." msgstr "" @@ -3168,7 +3176,7 @@ msgid "Successfully updated prompt." msgstr "" #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:46 -#: src/pages/providers/proxy/ProxyProviderForm.ts:46 +#: src/pages/providers/proxy/ProxyProviderForm.ts:48 #: src/pages/providers/saml/SAMLProviderForm.ts:43 msgid "Successfully updated provider." msgstr "" @@ -3317,7 +3325,7 @@ msgstr "" msgid "The URL \"{0}\" was not found." msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:123 +#: src/pages/providers/proxy/ProxyProviderForm.ts:131 msgid "The external URL you'll access the outpost at." msgstr "" @@ -3623,7 +3631,7 @@ msgstr "" msgid "Update {0}" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:107 +#: src/pages/providers/proxy/ProxyProviderForm.ts:82 msgid "Upstream host that the requests are forwarded to." msgstr "" @@ -3709,11 +3717,11 @@ msgstr "" msgid "User's display name." msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:67 +#: src/pages/providers/proxy/ProxyProviderForm.ts:69 msgid "User/Group Attribute used for the password part of the HTTP-Basic Header." msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:61 +#: src/pages/providers/proxy/ProxyProviderForm.ts:63 msgid "User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used." msgstr "" @@ -3754,7 +3762,7 @@ msgstr "" msgid "Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows." msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:116 +#: src/pages/providers/proxy/ProxyProviderForm.ts:91 msgid "Validate SSL Certificates of upstream servers." msgstr "" diff --git a/web/src/pages/providers/proxy/ProxyProviderForm.ts b/web/src/pages/providers/proxy/ProxyProviderForm.ts index b3fbfe493..25622a5a5 100644 --- a/web/src/pages/providers/proxy/ProxyProviderForm.ts +++ b/web/src/pages/providers/proxy/ProxyProviderForm.ts @@ -19,6 +19,7 @@ export class ProxyProviderFormPage extends Form { }).then(provider => { this.provider = provider; this.showHttpBasic = first(provider.basicAuthEnabled, true); + this.showInternalServer = first(!provider.forwardAuthMode, true); }); } @@ -28,6 +29,9 @@ export class ProxyProviderFormPage extends Form { @property({type: Boolean}) showHttpBasic = true; + @property({type: Boolean}) + showInternalServer = true; + getSuccessMessage(): string { if (this.provider) { return t`Successfully updated provider.`; @@ -67,6 +71,28 @@ export class ProxyProviderFormPage extends Form { `; } + renderInternalServer(): TemplateResult { + if (!this.showInternalServer) { + return html``; + } + return html` + +

${t`Upstream host that the requests are forwarded to.`}

+
+ +
+ + +
+

${t`Validate SSL Certificates of upstream servers.`}

+
`; + } + renderForm(): TemplateResult { return html`
{ ${t`Protocol settings`}
- - -

${t`Upstream host that the requests are forwarded to.`}

-
- -
- - -
-

${t`Validate SSL Certificates of upstream servers.`}

-
{

${t`The external URL you'll access the outpost at.`}

+ +
+ { + const el = ev.target as HTMLInputElement; + this.showInternalServer = !el.checked; + }}> + +
+

+ ${t`Enable this if you don't want to use this provider as a proxy, and want to use it with Traefik's forwardAuth or nginx's auth_request.`} +

+
+ ${this.renderInternalServer()}
diff --git a/website/docs/outposts/proxy.md b/website/docs/outposts/proxy.md deleted file mode 100644 index 2b3ed998e..000000000 --- a/website/docs/outposts/proxy.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Proxy Outpost ---- - -The proxy outpost sets the following headers: - -``` -X-Auth-Username: akadmin # The username of the currently logged in user -X-Forwarded-Email: root@localhost # The email address of the currently logged in user -X-Forwarded-Preferred-Username: akadmin # The username of the currently logged in user -X-Forwarded-User: 900347b8a29876b45ca6f75722635ecfedf0e931c6022e3a29a8aa13fb5516fb # The hashed identifier of the currently logged in user. -``` - -Additionally, you can set `additionalHeaders` on groups or users to set additional headers. - -If you enable *Set HTTP-Basic Authentication* option, the HTTP Authorization header is being set. diff --git a/website/docs/outposts/proxy.mdx b/website/docs/outposts/proxy.mdx new file mode 100644 index 000000000..0a24b2bab --- /dev/null +++ b/website/docs/outposts/proxy.mdx @@ -0,0 +1,229 @@ +--- +title: Proxy Outpost +--- + +The proxy outpost sets the following headers: + +``` +X-Auth-Username: akadmin # The username of the currently logged in user +X-Forwarded-Email: root@localhost # The email address of the currently logged in user +X-Forwarded-Preferred-Username: akadmin # The username of the currently logged in user +X-Forwarded-User: 900347b8a29876b45ca6f75722635ecfedf0e931c6022e3a29a8aa13fb5516fb # The hashed identifier of the currently logged in user. +``` + +Additionally, you can set `additionalHeaders` on groups or users to set additional headers. + +If you enable *Set HTTP-Basic Authentication* option, the HTTP Authorization header is being set. + +# Forward auth + +To use forward auth instead of proxying, you have to change a couple of settings. In the Proxy Provider, make sure to enable `Enable forward-auth mode` on the provider. + +## Nginx + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + +``` + location /akprox { + proxy_pass http://*ip of your outpost*:4180; + proxy_set_header X-Forwarded-Host $http_host; + error_page 401 = @akprox_signin; + } + + location @akprox_signin { + internal; + add_header Set-Cookie $auth_cookie; + return 302 /akprox/start?rd=$escaped_request_uri; + } + + location / { + auth_request /akprox/auth?nginx; + # All your other options... + } +``` + + + +Create a new ingress for the outpost + +```yaml +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + name: authentik-outpost +spec: + rules: + - host: *external host that you configured in authentik* + http: + paths: + - backend: + serviceName: authentik-outpost-*uuid of the service generated by authentik* + servicePort: 4180 + path: /akprox +``` + +This ingress handles authentication requests, and the sign-in flow. + +Add these annotations to the ingress you want to protect + +```yaml +metadata: + annotations: + nginx.ingress.kubernetes.io/auth-url: http://*external host that you configured in authentik*:4180/akprox/auth?nginx + nginx.ingress.kubernetes.io/auth-signin: http://*external host that you configured in authentik*:4180/akprox/start?rd=$escaped_request_uri + nginx.ingress.kubernetes.io/auth-snippet: | + proxy_set_header X-Forwarded-Host $http_host; +``` + + + +## Traefik + + + + +```yaml +http: + middlewares: + authentik: + forwardAuth: + address: http://authentik-outpost-*uuid of the service generated by authentik*:4180/akprox/auth?traefik + trustForwardHeader: true + authResponseHeaders: + - Set-Cookie + - X-Auth-Username + - X-Forwarded-Email + - X-Forwarded-Preferred-Username + - X-Forwarded-User + routers: + default-router: + rule: "Host(`*external host that you configured in authentik*`)" + middlewares: + - name: authentik + priority: 10 + services: # Unchanged + default-router-auth + match: "Host(`*external host that you configured in authentik*`) && PathPrefix(`/akprox/`)" + priority: 15 + services: http://*ip of your outpost*:4180/akprox +``` + + +```yaml +version: '3.7' +services: + traefik: + image: traefik:v2.2 + container_name: traefik + volumes: + - /var/run/docker.sock:/var/run/docker.sock + labels: + traefik.enable: true + traefik.http.routers.api.rule: Host(`traefik.example.com`) + traefik.http.routers.api.entrypoints: https + traefik.http.routers.api.service: api@internal + traefik.http.routers.api.tls: true + ports: + - 80:80 + - 443:443 + command: + - '--api' + - '--log=true' + - '--log.level=DEBUG' + - '--log.filepath=/var/log/traefik.log' + - '--providers.docker=true' + - '--providers.docker.exposedByDefault=false' + - '--entrypoints.http=true' + - '--entrypoints.http.address=:80' + - '--entrypoints.http.http.redirections.entrypoint.to=https' + - '--entrypoints.http.http.redirections.entrypoint.scheme=https' + - '--entrypoints.https=true' + - '--entrypoints.https.address=:443' + + authentik_proxy: + image: beryju/authentik-proxy:2021.4.4 + ports: + - 4180:4180 + - 4443:4443 + environment: + AUTHENTIK_HOST: https://your-authentik.tld + AUTHENTIK_INSECURE: "false" + AUTHENTIK_TOKEN: token-generated-by-authentik + labels: + traefik.enable: true + traefik.port: 4180 + traefik.http.routers.authentik.rule: Host(`*external host that you configured in authentik*`) && PathPrefix(`/akprox/`) + traefik.http.routers.authentik.entrypoints: https + traefik.http.routers.authentik.tls: true + traefik.http.middlewares.authentik.forwardauth.address: http://authentik_proxy:4180/akprox/auth?traefik + traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: true + traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: Set-Cookie,X-Auth-Username,X-Forwarded-Email,X-Forwarded-Preferred-Username,X-Forwarded-User + restart: unless-stopped + + whoami: + image: containous/whoami + labels: + traefik.enable: true + traefik.http.routers.whoami.rule: Host(`*external host that you configured in authentik*`) + traefik.http.routers.whoami.entrypoints: https + traefik.http.routers.whoami.tls: true + traefik.http.routers.whoami.middlewares: authentik@docker + restart: unless-stopped +``` + + +Create a middleware: + +```yaml +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: authentik +spec: + forwardAuth: + address: http://authentik-outpost-*uuid of the service generated by authentik*:4180/akprox/auth?traefik + trustForwardHeader: true + authResponseHeaders: + - Set-Cookie + - X-Auth-Username + - X-Forwarded-Email + - X-Forwarded-Preferred-Username + - X-Forwarded-User +``` + +Add the following settings to your IngressRoute + +```yaml +spec: + routes: + - kind: Rule + match: "Host(`*external host that you configured in authentik*`)" + middlewares: + - name: authentik + priority: 10 + services: # Unchanged + - kind: Rule + match: "Host(`*external host that you configured in authentik*`) && PathPrefix(`/akprox/`)" + priority: 15 + services: + - kind: Service + name: authentik-outpost-*uuid of the service generated by authentik* + port: 4180 +``` + +