191 lines
6.4 KiB
Go
191 lines
6.4 KiB
Go
|
package handlers
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"time"
|
||
|
|
||
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||
|
"github.com/authelia/authelia/v4/internal/utils"
|
||
|
)
|
||
|
|
||
|
// NewAuthzBuilder creates a new AuthzBuilder.
|
||
|
func NewAuthzBuilder() *AuthzBuilder {
|
||
|
return &AuthzBuilder{
|
||
|
config: AuthzConfig{RefreshInterval: time.Second * -1},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// WithStrategies replaces all strategies in this builder with the provided value.
|
||
|
func (b *AuthzBuilder) WithStrategies(strategies ...AuthnStrategy) *AuthzBuilder {
|
||
|
b.strategies = strategies
|
||
|
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
// WithStrategyCookie adds the Cookie header strategy to the strategies in this builder.
|
||
|
func (b *AuthzBuilder) WithStrategyCookie(refreshInterval time.Duration) *AuthzBuilder {
|
||
|
b.strategies = append(b.strategies, NewCookieSessionAuthnStrategy(refreshInterval))
|
||
|
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
// WithStrategyAuthorization adds the Authorization header strategy to the strategies in this builder.
|
||
|
func (b *AuthzBuilder) WithStrategyAuthorization() *AuthzBuilder {
|
||
|
b.strategies = append(b.strategies, NewHeaderAuthorizationAuthnStrategy())
|
||
|
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
// WithStrategyProxyAuthorization adds the Proxy-Authorization header strategy to the strategies in this builder.
|
||
|
func (b *AuthzBuilder) WithStrategyProxyAuthorization() *AuthzBuilder {
|
||
|
b.strategies = append(b.strategies, NewHeaderProxyAuthorizationAuthnStrategy())
|
||
|
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
// WithImplementationLegacy configures this builder to output an Authz which is used with the Legacy
|
||
|
// implementation which is a mix of the other implementations and usually works with most proxies.
|
||
|
func (b *AuthzBuilder) WithImplementationLegacy() *AuthzBuilder {
|
||
|
b.impl = AuthzImplLegacy
|
||
|
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
// WithImplementationForwardAuth configures this builder to output an Authz which is used with the ForwardAuth
|
||
|
// implementation traditionally used by Traefik, Caddy, and Skipper.
|
||
|
func (b *AuthzBuilder) WithImplementationForwardAuth() *AuthzBuilder {
|
||
|
b.impl = AuthzImplForwardAuth
|
||
|
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
// WithImplementationAuthRequest configures this builder to output an Authz which is used with the AuthRequest
|
||
|
// implementation traditionally used by NGINX.
|
||
|
func (b *AuthzBuilder) WithImplementationAuthRequest() *AuthzBuilder {
|
||
|
b.impl = AuthzImplAuthRequest
|
||
|
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
// WithImplementationExtAuthz configures this builder to output an Authz which is used with the ExtAuthz
|
||
|
// implementation traditionally used by Envoy.
|
||
|
func (b *AuthzBuilder) WithImplementationExtAuthz() *AuthzBuilder {
|
||
|
b.impl = AuthzImplExtAuthz
|
||
|
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
// WithConfig allows configuring the Authz config by providing a *schema.Configuration. This function converts it to
|
||
|
// an AuthzConfig and assigns it to the builder.
|
||
|
func (b *AuthzBuilder) WithConfig(config *schema.Configuration) *AuthzBuilder {
|
||
|
if config == nil {
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
var refreshInterval time.Duration
|
||
|
|
||
|
switch config.AuthenticationBackend.RefreshInterval {
|
||
|
case schema.ProfileRefreshDisabled:
|
||
|
refreshInterval = time.Second * -1
|
||
|
case schema.ProfileRefreshAlways:
|
||
|
refreshInterval = time.Second * 0
|
||
|
default:
|
||
|
refreshInterval, _ = utils.ParseDurationString(config.AuthenticationBackend.RefreshInterval)
|
||
|
}
|
||
|
|
||
|
b.config = AuthzConfig{
|
||
|
RefreshInterval: refreshInterval,
|
||
|
Domains: []AuthzDomain{
|
||
|
{
|
||
|
Name: fmt.Sprintf(".%s", config.Session.Domain),
|
||
|
PortalURL: nil,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
// WithEndpointConfig configures the AuthzBuilder with a *schema.ServerAuthzEndpointConfig. Should be called AFTER
|
||
|
// WithConfig or WithAuthzConfig.
|
||
|
func (b *AuthzBuilder) WithEndpointConfig(config schema.ServerAuthzEndpoint) *AuthzBuilder {
|
||
|
switch config.Implementation {
|
||
|
case AuthzImplForwardAuth.String():
|
||
|
b.WithImplementationForwardAuth()
|
||
|
case AuthzImplAuthRequest.String():
|
||
|
b.WithImplementationAuthRequest()
|
||
|
case AuthzImplExtAuthz.String():
|
||
|
b.WithImplementationExtAuthz()
|
||
|
default:
|
||
|
b.WithImplementationLegacy()
|
||
|
}
|
||
|
|
||
|
b.WithStrategies()
|
||
|
|
||
|
for _, strategy := range config.AuthnStrategies {
|
||
|
switch strategy.Name {
|
||
|
case AuthnStrategyCookieSession:
|
||
|
b.strategies = append(b.strategies, NewCookieSessionAuthnStrategy(b.config.RefreshInterval))
|
||
|
case AuthnStrategyHeaderAuthorization:
|
||
|
b.strategies = append(b.strategies, NewHeaderAuthorizationAuthnStrategy())
|
||
|
case AuthnStrategyHeaderProxyAuthorization:
|
||
|
b.strategies = append(b.strategies, NewHeaderProxyAuthorizationAuthnStrategy())
|
||
|
case AuthnStrategyHeaderAuthRequestProxyAuthorization:
|
||
|
b.strategies = append(b.strategies, NewHeaderProxyAuthorizationAuthRequestAuthnStrategy())
|
||
|
case AuthnStrategyHeaderLegacy:
|
||
|
b.strategies = append(b.strategies, NewHeaderLegacyAuthnStrategy())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
// WithAuthzConfig allows configuring the Authz config by providing a AuthzConfig directly. Recommended this is only
|
||
|
// used in testing and WithConfig is used instead.
|
||
|
func (b *AuthzBuilder) WithAuthzConfig(config AuthzConfig) *AuthzBuilder {
|
||
|
b.config = config
|
||
|
|
||
|
return b
|
||
|
}
|
||
|
|
||
|
// Build returns a new Authz from the currently configured options in this builder.
|
||
|
func (b *AuthzBuilder) Build() (authz *Authz) {
|
||
|
authz = &Authz{
|
||
|
config: b.config,
|
||
|
strategies: b.strategies,
|
||
|
handleAuthorized: handleAuthzAuthorizedStandard,
|
||
|
}
|
||
|
|
||
|
if len(authz.strategies) == 0 {
|
||
|
switch b.impl {
|
||
|
case AuthzImplLegacy:
|
||
|
authz.strategies = []AuthnStrategy{NewHeaderLegacyAuthnStrategy(), NewCookieSessionAuthnStrategy(b.config.RefreshInterval)}
|
||
|
case AuthzImplAuthRequest:
|
||
|
authz.strategies = []AuthnStrategy{NewHeaderProxyAuthorizationAuthRequestAuthnStrategy(), NewCookieSessionAuthnStrategy(b.config.RefreshInterval)}
|
||
|
default:
|
||
|
authz.strategies = []AuthnStrategy{NewHeaderProxyAuthorizationAuthnStrategy(), NewCookieSessionAuthnStrategy(b.config.RefreshInterval)}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
switch b.impl {
|
||
|
case AuthzImplLegacy:
|
||
|
authz.legacy = true
|
||
|
authz.handleGetObject = handleAuthzGetObjectLegacy
|
||
|
authz.handleUnauthorized = handleAuthzUnauthorizedLegacy
|
||
|
authz.handleGetAutheliaURL = handleAuthzPortalURLLegacy
|
||
|
case AuthzImplForwardAuth:
|
||
|
authz.handleGetObject = handleAuthzGetObjectForwardAuth
|
||
|
authz.handleUnauthorized = handleAuthzUnauthorizedForwardAuth
|
||
|
authz.handleGetAutheliaURL = handleAuthzPortalURLFromQuery
|
||
|
case AuthzImplAuthRequest:
|
||
|
authz.handleGetObject = handleAuthzGetObjectAuthRequest
|
||
|
authz.handleUnauthorized = handleAuthzUnauthorizedAuthRequest
|
||
|
case AuthzImplExtAuthz:
|
||
|
authz.handleGetObject = handleAuthzGetObjectExtAuthz
|
||
|
authz.handleUnauthorized = handleAuthzUnauthorizedExtAuthz
|
||
|
authz.handleGetAutheliaURL = handleAuthzPortalURLFromHeader
|
||
|
}
|
||
|
|
||
|
return authz
|
||
|
}
|