mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
fix(server): missing cache and xss headers (#3289)
Addresses documentation and a couple of headers which were missed.
This commit is contained in:
parent
cac8919f97
commit
0855ea2f71
|
@ -89,10 +89,15 @@ that users who have access to the database do not also have access to this key.
|
|||
|
||||
The encrypted data in the database is as follows:
|
||||
|
||||
| Table | Column | Rational |
|
||||
|:-------------------:|:----------:|:------------------------------------------------------------------------------------------------------:|
|
||||
| totp_configurations | secret | Prevents a [Leaked Database](#leaked-database) or [Bad Actors](#bad-actors) from compromising security |
|
||||
| webauthn_devices | public_key | Prevents [Bad Actors](#bad-actors) from compromising security |
|
||||
| Table | Column | Rational |
|
||||
|:---------------------------------:|:------------:|:------------------------------------------------------------------------------------------------------:|
|
||||
| totp_configurations | secret | Prevents a [Leaked Database](#leaked-database) or [Bad Actors](#bad-actors) from compromising security |
|
||||
| webauthn_devices | public_key | Prevents [Bad Actors](#bad-actors) from compromising security |
|
||||
| oauth2_authorization_code_session | session_data | Prevents [Bad Actors](#bad-actors) from compromising security |
|
||||
| oauth2_access_token_session | session_data | Prevents [Bad Actors](#bad-actors) from compromising security |
|
||||
| oauth2_refresh_token_session | session_data | Prevents [Bad Actors](#bad-actors) from compromising security |
|
||||
| oauth2_pkce_request_session | session_data | Prevents [Bad Actors](#bad-actors) from compromising security |
|
||||
| oauth2_openid_connect_session | session_data | Prevents [Bad Actors](#bad-actors) from compromising security |
|
||||
|
||||
### Leaked Database
|
||||
|
||||
|
@ -224,77 +229,70 @@ feature, and set the [expiration](../configuration/session/index.md#expiration)
|
|||
manner would mean if the cookie age was more than 2 hours or if the user was inactive for more than 10 minutes the
|
||||
session would be destroyed.
|
||||
|
||||
### Additional proxy protection measures
|
||||
### Response Headers
|
||||
|
||||
You can also apply the following headers to your proxy configuration for improving security. Please read the
|
||||
relevant documentation for these headers before applying them blindly.
|
||||
This document previously detailed additional per-proxy configuration options that could be utilized in a proxy to
|
||||
improve security. These headers are now documented here and implemented by default in all responses due to the fact
|
||||
the experience should be the same regardless of which proxy you're utilizing and the area is rapidly evolving.
|
||||
|
||||
#### nginx
|
||||
Users who need custom behaviours in this area can submit a request or remove/replace the headers as necessary.
|
||||
|
||||
```
|
||||
# We don't want any credentials / TOTP secret key / QR code to be cached by
|
||||
# the client
|
||||
add_header Cache-Control "no-store";
|
||||
add_header Pragma "no-cache";
|
||||
#### X-Content-Type-Options
|
||||
|
||||
# Clickjacking / XSS protection
|
||||
**Value:** `nosniff`
|
||||
**Endpoints:** All
|
||||
|
||||
# We don't want Authelia's login page to be rendered within a <frame>,
|
||||
# <iframe> or <object> from an external website.
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
Prevents MIME type sniffing. See the
|
||||
[MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options) for more information.
|
||||
|
||||
# Block pages from loading when they detect reflected XSS attacks.
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
```
|
||||
#### Referrer-Policy
|
||||
|
||||
**Value:** `strict-origin-when-cross-origin`
|
||||
**Endpoints:** All
|
||||
|
||||
#### Traefik 2.x - Kubernetes CRD
|
||||
Sends only the origin as the referrer in cross-origin requests, but sends the origin, path, and query string in
|
||||
same-origin requests. See the
|
||||
[MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) for more information.
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: headers-authelia
|
||||
spec:
|
||||
headers:
|
||||
browserXssFilter: true
|
||||
customFrameOptionsValue: "SAMEORIGIN"
|
||||
customResponseHeaders:
|
||||
Cache-Control: "no-store"
|
||||
Pragma: "no-cache"
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: authelia
|
||||
spec:
|
||||
entryPoints:
|
||||
- http
|
||||
routes:
|
||||
- match: Host(`auth.example.com`) && PathPrefix(`/`)
|
||||
kind: Rule
|
||||
priority: 1
|
||||
middlewares:
|
||||
- name: headers-authelia
|
||||
namespace: authelia
|
||||
services:
|
||||
- name: authelia
|
||||
port: 80
|
||||
```
|
||||
#### X-Frame-Options
|
||||
|
||||
#### Traefik 2.x - docker-compose
|
||||
**Value:** `SAMEORIGIN`
|
||||
**Endpoints:** All
|
||||
|
||||
```yaml
|
||||
services:
|
||||
authelia:
|
||||
labels:
|
||||
- "traefik.http.routers.authelia.middlewares=authelia-headers"
|
||||
- "traefik.http.middlewares.authelia-headers.headers.browserXssFilter=true"
|
||||
- "traefik.http.middlewares.authelia-headers.headers.customFrameOptionsValue=SAMEORIGIN"
|
||||
- "traefik.http.middlewares.authelia-headers.headers.customResponseHeaders.Cache-Control=no-store"
|
||||
- "traefik.http.middlewares.authelia-headers.headers.customResponseHeaders.Pragma=no-cache"
|
||||
```
|
||||
Prevents Authelia rendering in a `frame`, `iframe`, `embed`, or `object` element. See the
|
||||
[MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) for more information.
|
||||
|
||||
#### X-XSS-Protection
|
||||
|
||||
**Value:** `0`
|
||||
**Endpoints:** All
|
||||
|
||||
We disable this as this feature is not present in any modern browser and could introduce vulnerabilities if enabled at
|
||||
all. Going forward [CORS], [CORP], CORB, and [COEP] are the standards for browser centric site security. See the
|
||||
[MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection) for more information.
|
||||
|
||||
#### Permissions-Policy
|
||||
|
||||
**Value:** `interest-cohort=()`
|
||||
**Endpoints:** All
|
||||
|
||||
Disables FLoC Cohorts.
|
||||
|
||||
#### Pragma
|
||||
|
||||
**Value:** `no-cache`
|
||||
**Endpoints:** API
|
||||
|
||||
Disables caching of API requests on HTTP/1.0 browsers. See the
|
||||
[MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Pragma) for more information.
|
||||
|
||||
#### Cache-Control
|
||||
|
||||
**Value:** `no-store`
|
||||
**Endpoints:** API
|
||||
|
||||
Disables caching responses entirely on HTTP/1.1 browsers. See the
|
||||
[MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) for more information.
|
||||
|
||||
### More protections measures with fail2ban
|
||||
|
||||
|
@ -438,3 +436,6 @@ services:
|
|||
```
|
||||
|
||||
[HSTS]: https://www.nginx.com/blog/http-strict-transport-security-hsts-and-nginx/
|
||||
[CORS]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
||||
[CORP]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cross-Origin_Resource_Policy_(CORP)
|
||||
[COEP]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy
|
|
@ -41,9 +41,9 @@ func NewAutheliaCtx(ctx *fasthttp.RequestCtx, configuration schema.Configuration
|
|||
}
|
||||
|
||||
// AutheliaMiddleware is wrapping the RequestCtx into an AutheliaCtx providing Authelia related objects.
|
||||
func AutheliaMiddleware(configuration schema.Configuration, providers Providers) RequestHandlerBridge {
|
||||
func AutheliaMiddleware(configuration schema.Configuration, providers Providers, middlewares ...StandardMiddleware) RequestHandlerBridge {
|
||||
return func(next RequestHandler) fasthttp.RequestHandler {
|
||||
return func(ctx *fasthttp.RequestCtx) {
|
||||
bridge := func(ctx *fasthttp.RequestCtx) {
|
||||
autheliaCtx, err := NewAutheliaCtx(ctx, configuration, providers)
|
||||
if err != nil {
|
||||
autheliaCtx.Error(err, messageOperationFailed)
|
||||
|
@ -52,6 +52,12 @@ func AutheliaMiddleware(configuration schema.Configuration, providers Providers)
|
|||
|
||||
next(autheliaCtx)
|
||||
}
|
||||
|
||||
for i := len(middlewares) - 1; i >= 0; i-- {
|
||||
bridge = middlewares[i](bridge)
|
||||
}
|
||||
|
||||
return bridge
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,9 +31,15 @@ var (
|
|||
headerAccessControlRequestHeaders = []byte(fasthttp.HeaderAccessControlRequestHeaders)
|
||||
headerAccessControlRequestMethod = []byte(fasthttp.HeaderAccessControlRequestMethod)
|
||||
|
||||
headerXContentTypeOptions = []byte(fasthttp.HeaderXContentTypeOptions)
|
||||
headerReferrerPolicy = []byte(fasthttp.HeaderReferrerPolicy)
|
||||
headerPermissionsPolicy = []byte("Permissions-Policy")
|
||||
headerXContentTypeOptions = []byte(fasthttp.HeaderXContentTypeOptions)
|
||||
headerReferrerPolicy = []byte(fasthttp.HeaderReferrerPolicy)
|
||||
headerXFrameOptions = []byte(fasthttp.HeaderXFrameOptions)
|
||||
headerPragma = []byte(fasthttp.HeaderPragma)
|
||||
headerCacheControl = []byte(fasthttp.HeaderCacheControl)
|
||||
headerXXSSProtection = []byte(fasthttp.HeaderXXSSProtection)
|
||||
headerContentSecurityPolicy = []byte(fasthttp.HeaderContentSecurityPolicy)
|
||||
|
||||
headerPermissionsPolicy = []byte("Permissions-Policy")
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -44,9 +50,14 @@ var (
|
|||
headerValueVaryWildcard = []byte("Accept-Encoding")
|
||||
headerValueOriginWildcard = []byte("*")
|
||||
headerValueZero = []byte("0")
|
||||
headerValueCSPNone = []byte("default-src 'none';")
|
||||
|
||||
headerValueNoSniff = []byte("nosniff")
|
||||
headerValueStrictOriginCrossOrigin = []byte("strict-origin-when-cross-origin")
|
||||
headerValueSameOrigin = []byte("SAMEORIGIN")
|
||||
headerValueNoCache = []byte("no-cache")
|
||||
headerValueNoStore = []byte("no-store")
|
||||
headerValueXSSModeBlock = []byte("1; mode=block")
|
||||
headerValueCohort = []byte("interest-cohort=()")
|
||||
)
|
||||
|
||||
|
|
|
@ -10,6 +10,27 @@ func SecurityHeaders(next fasthttp.RequestHandler) fasthttp.RequestHandler {
|
|||
ctx.Response.Header.SetBytesKV(headerXContentTypeOptions, headerValueNoSniff)
|
||||
ctx.Response.Header.SetBytesKV(headerReferrerPolicy, headerValueStrictOriginCrossOrigin)
|
||||
ctx.Response.Header.SetBytesKV(headerPermissionsPolicy, headerValueCohort)
|
||||
ctx.Response.Header.SetBytesKV(headerXFrameOptions, headerValueSameOrigin)
|
||||
ctx.Response.Header.SetBytesKV(headerXXSSProtection, headerValueXSSModeBlock)
|
||||
|
||||
next(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// SecurityHeadersCSPNone middleware adds the Content-Security-Policy header with the value "default-src 'none';".
|
||||
func SecurityHeadersCSPNone(next fasthttp.RequestHandler) fasthttp.RequestHandler {
|
||||
return func(ctx *fasthttp.RequestCtx) {
|
||||
ctx.Response.Header.SetBytesKV(headerContentSecurityPolicy, headerValueCSPNone)
|
||||
|
||||
next(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// SecurityHeadersNoStore middleware adds the Pragma no-cache and Cache-Control no-store headers.
|
||||
func SecurityHeadersNoStore(next fasthttp.RequestHandler) fasthttp.RequestHandler {
|
||||
return func(ctx *fasthttp.RequestCtx) {
|
||||
ctx.Response.Header.SetBytesKV(headerPragma, headerValueNoCache)
|
||||
ctx.Response.Header.SetBytesKV(headerCacheControl, headerValueNoStore)
|
||||
|
||||
next(ctx)
|
||||
}
|
||||
|
|
|
@ -7,17 +7,19 @@ import (
|
|||
)
|
||||
|
||||
// StripPath strips the first level of a path.
|
||||
func StripPath(path string, next fasthttp.RequestHandler) fasthttp.RequestHandler {
|
||||
return func(ctx *fasthttp.RequestCtx) {
|
||||
uri := ctx.RequestURI()
|
||||
func StripPath(path string) (middleware StandardMiddleware) {
|
||||
return func(next fasthttp.RequestHandler) fasthttp.RequestHandler {
|
||||
return func(ctx *fasthttp.RequestCtx) {
|
||||
uri := ctx.RequestURI()
|
||||
|
||||
if strings.HasPrefix(string(uri), path) {
|
||||
ctx.SetUserValueBytes(UserValueKeyBaseURL, path)
|
||||
if strings.HasPrefix(string(uri), path) {
|
||||
ctx.SetUserValueBytes(UserValueKeyBaseURL, path)
|
||||
|
||||
newURI := strings.TrimPrefix(string(uri), path)
|
||||
ctx.Request.SetRequestURI(newURI)
|
||||
newURI := strings.TrimPrefix(string(uri), path)
|
||||
ctx.Request.SetRequestURI(newURI)
|
||||
}
|
||||
|
||||
next(ctx)
|
||||
}
|
||||
|
||||
next(ctx)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ type RequestHandler = func(*AutheliaCtx)
|
|||
// Middleware represent an Authelia middleware.
|
||||
type Middleware = func(RequestHandler) RequestHandler
|
||||
|
||||
// StandardMiddleware represents a fasthttp middleware.
|
||||
type StandardMiddleware = func(next fasthttp.RequestHandler) (handler fasthttp.RequestHandler)
|
||||
|
||||
// RequestHandlerBridge bridge a AutheliaCtx handle to a RequestHandler handler.
|
||||
type RequestHandlerBridge = func(RequestHandler) fasthttp.RequestHandler
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ func getHandler(config schema.Configuration, providers middlewares.Providers) fa
|
|||
handlerPublicHTML := newPublicHTMLEmbeddedHandler()
|
||||
handlerLocales := newLocalesEmbeddedHandler()
|
||||
|
||||
middleware := middlewares.AutheliaMiddleware(config, providers)
|
||||
middleware := middlewares.AutheliaMiddleware(config, providers, middlewares.SecurityHeaders)
|
||||
|
||||
policyCORSPublicGET := middlewares.NewCORSPolicyBuilder().
|
||||
WithAllowedMethods("OPTIONS", "GET").
|
||||
|
@ -134,53 +134,58 @@ func getHandler(config schema.Configuration, providers middlewares.Providers) fa
|
|||
r.GET("/api/"+file, handlerPublicHTML)
|
||||
}
|
||||
|
||||
r.GET("/api/health", middleware(handlers.HealthGET))
|
||||
r.GET("/api/state", middleware(handlers.StateGET))
|
||||
middlewareAPI := middlewares.AutheliaMiddleware(
|
||||
config, providers,
|
||||
middlewares.SecurityHeaders, middlewares.SecurityHeadersNoStore, middlewares.SecurityHeadersCSPNone,
|
||||
)
|
||||
|
||||
r.GET("/api/configuration", middleware(middlewares.Require1FA(handlers.ConfigurationGET)))
|
||||
r.GET("/api/health", middlewareAPI(handlers.HealthGET))
|
||||
r.GET("/api/state", middlewareAPI(handlers.StateGET))
|
||||
|
||||
r.GET("/api/configuration/password-policy", middleware(handlers.PasswordPolicyConfigurationGet))
|
||||
r.GET("/api/configuration", middlewareAPI(middlewares.Require1FA(handlers.ConfigurationGET)))
|
||||
|
||||
r.GET("/api/verify", middleware(handlers.VerifyGET(config.AuthenticationBackend)))
|
||||
r.HEAD("/api/verify", middleware(handlers.VerifyGET(config.AuthenticationBackend)))
|
||||
r.GET("/api/configuration/password-policy", middlewareAPI(handlers.PasswordPolicyConfigurationGet))
|
||||
|
||||
r.POST("/api/checks/safe-redirection", middleware(handlers.CheckSafeRedirectionPOST))
|
||||
r.GET("/api/verify", middlewareAPI(handlers.VerifyGET(config.AuthenticationBackend)))
|
||||
r.HEAD("/api/verify", middlewareAPI(handlers.VerifyGET(config.AuthenticationBackend)))
|
||||
|
||||
r.POST("/api/checks/safe-redirection", middlewareAPI(handlers.CheckSafeRedirectionPOST))
|
||||
|
||||
delayFunc := middlewares.TimingAttackDelay(10, 250, 85, time.Second)
|
||||
|
||||
r.POST("/api/firstfactor", middleware(handlers.FirstFactorPOST(delayFunc)))
|
||||
r.POST("/api/logout", middleware(handlers.LogoutPOST))
|
||||
r.POST("/api/firstfactor", middlewareAPI(handlers.FirstFactorPOST(delayFunc)))
|
||||
r.POST("/api/logout", middlewareAPI(handlers.LogoutPOST))
|
||||
|
||||
// Only register endpoints if forgot password is not disabled.
|
||||
if !config.AuthenticationBackend.DisableResetPassword &&
|
||||
config.AuthenticationBackend.PasswordReset.CustomURL.String() == "" {
|
||||
// Password reset related endpoints.
|
||||
r.POST("/api/reset-password/identity/start", middleware(handlers.ResetPasswordIdentityStart))
|
||||
r.POST("/api/reset-password/identity/finish", middleware(handlers.ResetPasswordIdentityFinish))
|
||||
r.POST("/api/reset-password", middleware(handlers.ResetPasswordPOST))
|
||||
r.POST("/api/reset-password/identity/start", middlewareAPI(handlers.ResetPasswordIdentityStart))
|
||||
r.POST("/api/reset-password/identity/finish", middlewareAPI(handlers.ResetPasswordIdentityFinish))
|
||||
r.POST("/api/reset-password", middlewareAPI(handlers.ResetPasswordPOST))
|
||||
}
|
||||
|
||||
// Information about the user.
|
||||
r.GET("/api/user/info", middleware(middlewares.Require1FA(handlers.UserInfoGET)))
|
||||
r.POST("/api/user/info", middleware(middlewares.Require1FA(handlers.UserInfoPOST)))
|
||||
r.POST("/api/user/info/2fa_method", middleware(middlewares.Require1FA(handlers.MethodPreferencePOST)))
|
||||
r.GET("/api/user/info", middlewareAPI(middlewares.Require1FA(handlers.UserInfoGET)))
|
||||
r.POST("/api/user/info", middlewareAPI(middlewares.Require1FA(handlers.UserInfoPOST)))
|
||||
r.POST("/api/user/info/2fa_method", middlewareAPI(middlewares.Require1FA(handlers.MethodPreferencePOST)))
|
||||
|
||||
if !config.TOTP.Disable {
|
||||
// TOTP related endpoints.
|
||||
r.GET("/api/user/info/totp", middleware(middlewares.Require1FA(handlers.UserTOTPInfoGET)))
|
||||
r.POST("/api/secondfactor/totp/identity/start", middleware(middlewares.Require1FA(handlers.TOTPIdentityStart)))
|
||||
r.POST("/api/secondfactor/totp/identity/finish", middleware(middlewares.Require1FA(handlers.TOTPIdentityFinish)))
|
||||
r.POST("/api/secondfactor/totp", middleware(middlewares.Require1FA(handlers.TimeBasedOneTimePasswordPOST)))
|
||||
r.GET("/api/user/info/totp", middlewareAPI(middlewares.Require1FA(handlers.UserTOTPInfoGET)))
|
||||
r.POST("/api/secondfactor/totp/identity/start", middlewareAPI(middlewares.Require1FA(handlers.TOTPIdentityStart)))
|
||||
r.POST("/api/secondfactor/totp/identity/finish", middlewareAPI(middlewares.Require1FA(handlers.TOTPIdentityFinish)))
|
||||
r.POST("/api/secondfactor/totp", middlewareAPI(middlewares.Require1FA(handlers.TimeBasedOneTimePasswordPOST)))
|
||||
}
|
||||
|
||||
if !config.Webauthn.Disable {
|
||||
// Webauthn Endpoints.
|
||||
r.POST("/api/secondfactor/webauthn/identity/start", middleware(middlewares.Require1FA(handlers.WebauthnIdentityStart)))
|
||||
r.POST("/api/secondfactor/webauthn/identity/finish", middleware(middlewares.Require1FA(handlers.WebauthnIdentityFinish)))
|
||||
r.POST("/api/secondfactor/webauthn/attestation", middleware(middlewares.Require1FA(handlers.WebauthnAttestationPOST)))
|
||||
r.POST("/api/secondfactor/webauthn/identity/start", middlewareAPI(middlewares.Require1FA(handlers.WebauthnIdentityStart)))
|
||||
r.POST("/api/secondfactor/webauthn/identity/finish", middlewareAPI(middlewares.Require1FA(handlers.WebauthnIdentityFinish)))
|
||||
r.POST("/api/secondfactor/webauthn/attestation", middlewareAPI(middlewares.Require1FA(handlers.WebauthnAttestationPOST)))
|
||||
|
||||
r.GET("/api/secondfactor/webauthn/assertion", middleware(middlewares.Require1FA(handlers.WebauthnAssertionGET)))
|
||||
r.POST("/api/secondfactor/webauthn/assertion", middleware(middlewares.Require1FA(handlers.WebauthnAssertionPOST)))
|
||||
r.GET("/api/secondfactor/webauthn/assertion", middlewareAPI(middlewares.Require1FA(handlers.WebauthnAssertionGET)))
|
||||
r.POST("/api/secondfactor/webauthn/assertion", middlewareAPI(middlewares.Require1FA(handlers.WebauthnAssertionPOST)))
|
||||
}
|
||||
|
||||
// Configure DUO api endpoint only if configuration exists.
|
||||
|
@ -198,9 +203,9 @@ func getHandler(config schema.Configuration, providers middlewares.Providers) fa
|
|||
config.DuoAPI.Hostname, ""))
|
||||
}
|
||||
|
||||
r.GET("/api/secondfactor/duo_devices", middleware(middlewares.Require1FA(handlers.DuoDevicesGET(duoAPI))))
|
||||
r.POST("/api/secondfactor/duo", middleware(middlewares.Require1FA(handlers.DuoPOST(duoAPI))))
|
||||
r.POST("/api/secondfactor/duo_device", middleware(middlewares.Require1FA(handlers.DuoDevicePOST)))
|
||||
r.GET("/api/secondfactor/duo_devices", middlewareAPI(middlewares.Require1FA(handlers.DuoDevicesGET(duoAPI))))
|
||||
r.POST("/api/secondfactor/duo", middlewareAPI(middlewares.Require1FA(handlers.DuoPOST(duoAPI))))
|
||||
r.POST("/api/secondfactor/duo_device", middlewareAPI(middlewares.Require1FA(handlers.DuoDevicePOST)))
|
||||
}
|
||||
|
||||
if config.Server.EnablePprof {
|
||||
|
@ -212,23 +217,23 @@ func getHandler(config schema.Configuration, providers middlewares.Providers) fa
|
|||
}
|
||||
|
||||
if providers.OpenIDConnect.Fosite != nil {
|
||||
r.GET("/api/oidc/consent", middleware(handlers.OpenIDConnectConsentGET))
|
||||
r.POST("/api/oidc/consent", middleware(handlers.OpenIDConnectConsentPOST))
|
||||
r.GET("/api/oidc/consent", middlewareAPI(handlers.OpenIDConnectConsentGET))
|
||||
r.POST("/api/oidc/consent", middlewareAPI(handlers.OpenIDConnectConsentPOST))
|
||||
|
||||
allowedOrigins := utils.StringSliceFromURLs(config.IdentityProviders.OIDC.CORS.AllowedOrigins)
|
||||
|
||||
r.OPTIONS(oidc.WellKnownOpenIDConfigurationPath, policyCORSPublicGET.HandleOPTIONS)
|
||||
r.GET(oidc.WellKnownOpenIDConfigurationPath, policyCORSPublicGET.Middleware(middleware(handlers.OpenIDConnectConfigurationWellKnownGET)))
|
||||
r.GET(oidc.WellKnownOpenIDConfigurationPath, policyCORSPublicGET.Middleware(middlewareAPI(handlers.OpenIDConnectConfigurationWellKnownGET)))
|
||||
|
||||
r.OPTIONS(oidc.WellKnownOAuthAuthorizationServerPath, policyCORSPublicGET.HandleOPTIONS)
|
||||
r.GET(oidc.WellKnownOAuthAuthorizationServerPath, policyCORSPublicGET.Middleware(middleware(handlers.OAuthAuthorizationServerWellKnownGET)))
|
||||
r.GET(oidc.WellKnownOAuthAuthorizationServerPath, policyCORSPublicGET.Middleware(middlewareAPI(handlers.OAuthAuthorizationServerWellKnownGET)))
|
||||
|
||||
r.OPTIONS(oidc.JWKsPath, policyCORSPublicGET.HandleOPTIONS)
|
||||
r.GET(oidc.JWKsPath, policyCORSPublicGET.Middleware(middleware(handlers.JSONWebKeySetGET)))
|
||||
r.GET(oidc.JWKsPath, policyCORSPublicGET.Middleware(middlewareAPI(handlers.JSONWebKeySetGET)))
|
||||
|
||||
// TODO (james-d-elliott): Remove in GA. This is a legacy implementation of the above endpoint.
|
||||
r.OPTIONS("/api/oidc/jwks", policyCORSPublicGET.HandleOPTIONS)
|
||||
r.GET("/api/oidc/jwks", policyCORSPublicGET.Middleware(middleware(handlers.JSONWebKeySetGET)))
|
||||
r.GET("/api/oidc/jwks", policyCORSPublicGET.Middleware(middlewareAPI(handlers.JSONWebKeySetGET)))
|
||||
|
||||
policyCORSAuthorization := middlewares.NewCORSPolicyBuilder().
|
||||
WithAllowedMethods("OPTIONS", "GET").
|
||||
|
@ -237,11 +242,11 @@ func getHandler(config schema.Configuration, providers middlewares.Providers) fa
|
|||
Build()
|
||||
|
||||
r.OPTIONS(oidc.AuthorizationPath, policyCORSAuthorization.HandleOnlyOPTIONS)
|
||||
r.GET(oidc.AuthorizationPath, middleware(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectAuthorizationGET)))
|
||||
r.GET(oidc.AuthorizationPath, middlewareAPI(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectAuthorizationGET)))
|
||||
|
||||
// TODO (james-d-elliott): Remove in GA. This is a legacy endpoint.
|
||||
r.OPTIONS("/api/oidc/authorize", policyCORSAuthorization.HandleOnlyOPTIONS)
|
||||
r.GET("/api/oidc/authorize", middleware(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectAuthorizationGET)))
|
||||
r.GET("/api/oidc/authorize", middlewareAPI(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectAuthorizationGET)))
|
||||
|
||||
policyCORSToken := middlewares.NewCORSPolicyBuilder().
|
||||
WithAllowCredentials(true).
|
||||
|
@ -251,7 +256,7 @@ func getHandler(config schema.Configuration, providers middlewares.Providers) fa
|
|||
Build()
|
||||
|
||||
r.OPTIONS(oidc.TokenPath, policyCORSToken.HandleOPTIONS)
|
||||
r.POST(oidc.TokenPath, policyCORSToken.Middleware(middleware(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectTokenPOST))))
|
||||
r.POST(oidc.TokenPath, policyCORSToken.Middleware(middlewareAPI(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectTokenPOST))))
|
||||
|
||||
policyCORSUserinfo := middlewares.NewCORSPolicyBuilder().
|
||||
WithAllowCredentials(true).
|
||||
|
@ -261,8 +266,8 @@ func getHandler(config schema.Configuration, providers middlewares.Providers) fa
|
|||
Build()
|
||||
|
||||
r.OPTIONS(oidc.UserinfoPath, policyCORSUserinfo.HandleOPTIONS)
|
||||
r.GET(oidc.UserinfoPath, policyCORSUserinfo.Middleware(middleware(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectUserinfo))))
|
||||
r.POST(oidc.UserinfoPath, policyCORSUserinfo.Middleware(middleware(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectUserinfo))))
|
||||
r.GET(oidc.UserinfoPath, policyCORSUserinfo.Middleware(middlewareAPI(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectUserinfo))))
|
||||
r.POST(oidc.UserinfoPath, policyCORSUserinfo.Middleware(middlewareAPI(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OpenIDConnectUserinfo))))
|
||||
|
||||
policyCORSIntrospection := middlewares.NewCORSPolicyBuilder().
|
||||
WithAllowCredentials(true).
|
||||
|
@ -272,11 +277,11 @@ func getHandler(config schema.Configuration, providers middlewares.Providers) fa
|
|||
Build()
|
||||
|
||||
r.OPTIONS(oidc.IntrospectionPath, policyCORSIntrospection.HandleOPTIONS)
|
||||
r.POST(oidc.IntrospectionPath, policyCORSIntrospection.Middleware(middleware(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OAuthIntrospectionPOST))))
|
||||
r.POST(oidc.IntrospectionPath, policyCORSIntrospection.Middleware(middlewareAPI(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OAuthIntrospectionPOST))))
|
||||
|
||||
// TODO (james-d-elliott): Remove in GA. This is a legacy implementation of the above endpoint.
|
||||
r.OPTIONS("/api/oidc/introspect", policyCORSIntrospection.HandleOPTIONS)
|
||||
r.POST("/api/oidc/introspect", policyCORSIntrospection.Middleware(middleware(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OAuthIntrospectionPOST))))
|
||||
r.POST("/api/oidc/introspect", policyCORSIntrospection.Middleware(middlewareAPI(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OAuthIntrospectionPOST))))
|
||||
|
||||
policyCORSRevocation := middlewares.NewCORSPolicyBuilder().
|
||||
WithAllowCredentials(true).
|
||||
|
@ -286,11 +291,11 @@ func getHandler(config schema.Configuration, providers middlewares.Providers) fa
|
|||
Build()
|
||||
|
||||
r.OPTIONS(oidc.RevocationPath, policyCORSRevocation.HandleOPTIONS)
|
||||
r.POST(oidc.RevocationPath, policyCORSRevocation.Middleware(middleware(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OAuthRevocationPOST))))
|
||||
r.POST(oidc.RevocationPath, policyCORSRevocation.Middleware(middlewareAPI(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OAuthRevocationPOST))))
|
||||
|
||||
// TODO (james-d-elliott): Remove in GA. This is a legacy implementation of the above endpoint.
|
||||
r.OPTIONS("/api/oidc/revoke", policyCORSRevocation.HandleOPTIONS)
|
||||
r.POST("/api/oidc/revoke", policyCORSRevocation.Middleware(middleware(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OAuthRevocationPOST))))
|
||||
r.POST("/api/oidc/revoke", policyCORSRevocation.Middleware(middlewareAPI(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OAuthRevocationPOST))))
|
||||
}
|
||||
|
||||
r.NotFound = handlerNotFound(middleware(serveIndexHandler))
|
||||
|
@ -298,10 +303,9 @@ func getHandler(config schema.Configuration, providers middlewares.Providers) fa
|
|||
r.HandleMethodNotAllowed = true
|
||||
r.MethodNotAllowed = handlerMethodNotAllowed
|
||||
|
||||
handler := middlewares.LogRequest(middlewares.SecurityHeaders(r.Handler))
|
||||
if config.Server.Path != "" {
|
||||
handler = middlewares.StripPath(config.Server.Path, handler)
|
||||
return middlewares.StripPath(config.Server.Path)(middlewares.LogRequest(r.Handler))
|
||||
}
|
||||
|
||||
return handler
|
||||
return middlewares.LogRequest(r.Handler)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user