/
handler_authz_builder.go
147 lines (122 loc) · 5.29 KB
/
handler_authz_builder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package handlers
import (
"github.com/valyala/fasthttp"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/model"
)
// NewAuthzBuilder creates a new AuthzBuilder.
func NewAuthzBuilder() *AuthzBuilder {
return &AuthzBuilder{
config: AuthzConfig{RefreshInterval: schema.NewRefreshIntervalDurationAlways()},
}
}
// WithStrategies replaces all strategies in this builder with the provided value.
func (b *AuthzBuilder) WithStrategies(strategies ...AuthnStrategy) *AuthzBuilder {
b.strategies = strategies
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.implementation = 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.implementation = 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.implementation = 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.implementation = 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
}
b.config = AuthzConfig{
RefreshInterval: config.AuthenticationBackend.RefreshInterval,
}
return b
}
// WithEndpointConfig configures the AuthzBuilder with a *schema.ServerAuthzEndpointConfig. Should be called AFTER
// WithConfig or WithAuthzConfig.
func (b *AuthzBuilder) WithEndpointConfig(config schema.ServerEndpointsAuthz) *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(strategy.Schemes...))
case AuthnStrategyHeaderProxyAuthorization:
b.strategies = append(b.strategies, NewHeaderProxyAuthorizationAuthnStrategy(strategy.Schemes...))
case AuthnStrategyHeaderAuthRequestProxyAuthorization:
b.strategies = append(b.strategies, NewHeaderProxyAuthorizationAuthRequestAuthnStrategy(strategy.Schemes...))
case AuthnStrategyHeaderLegacy:
b.strategies = append(b.strategies, NewHeaderLegacyAuthnStrategy())
}
}
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,
implementation: b.implementation,
}
authz.config.StatusCodeBadRequest = fasthttp.StatusBadRequest
if len(authz.strategies) == 0 {
switch b.implementation {
case AuthzImplLegacy:
authz.strategies = []AuthnStrategy{NewHeaderLegacyAuthnStrategy(), NewCookieSessionAuthnStrategy(b.config.RefreshInterval)}
case AuthzImplAuthRequest:
authz.strategies = []AuthnStrategy{NewHeaderProxyAuthorizationAuthRequestAuthnStrategy(model.AuthorizationSchemeBasic.String()), NewCookieSessionAuthnStrategy(b.config.RefreshInterval)}
default:
authz.strategies = []AuthnStrategy{NewHeaderProxyAuthorizationAuthnStrategy(model.AuthorizationSchemeBasic.String()), NewCookieSessionAuthnStrategy(b.config.RefreshInterval)}
}
}
switch b.implementation {
case AuthzImplLegacy:
authz.config.StatusCodeBadRequest = fasthttp.StatusUnauthorized
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
authz.handleGetAutheliaURL = handleAuthzPortalURLFromQuery
case AuthzImplExtAuthz:
authz.handleGetObject = handleAuthzGetObjectExtAuthz
authz.handleUnauthorized = handleAuthzUnauthorizedExtAuthz
authz.handleGetAutheliaURL = handleAuthzPortalURLFromHeader
}
return authz
}