-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.go
145 lines (131 loc) · 5.85 KB
/
config.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
package goauth
import (
"context"
"strings"
"time"
"github.com/bancodobrasil/goauth/handler"
"github.com/bancodobrasil/goauth/log"
"github.com/spf13/viper"
)
// APIKeyConfig is the config to be used on the VerifyAPIKey handler
type APIKeyConfig struct {
// Header is the header to be used on the VerifyAPIKey handler. Defaults to X-API-Key
Header string `mapstructure:"GOAUTH_API_KEY_HEADER"`
// KeyList is the list of API keys to be used on the VerifyAPIKey handler, separated by comma
KeyList []string `mapstructure:"GOAUTH_API_KEY_LIST"`
}
// JWKSConfig is the config to be used on the VerifyJWKS handler
type JWKSConfig struct {
// Header is the header to be used on the VerifyJWKS handler. Defaults to Authorization
Header string `mapstructure:"GOAUTH_JWKS_HEADER"`
// TokenType is the token type to be used on the VerifyJWKS handler. Defaults to Bearer
TokenType string `mapstructure:"GOAUTH_JWKS_TOKEN_TYPE"`
// URL is the JWKS endpoint to be used on the VerifyJWKS handler
URL string `mapstructure:"GOAUTH_JWKS_URL"`
// RefreshWindow is the time window before checking if the JWKS cache needs to be refreshed, in seconds. Defaults to 60
RefreshWindow int `mapstructure:"GOAUTH_JWKS_REFRESH_WINDOW"`
// MinRefreshInterval is the minimum interval between JWKS refreshes, in seconds. Defaults to 300
MinRefreshInterval int `mapstructure:"GOAUTH_JWKS_MIN_REFRESH_INTERVAL"`
// PayloadContextKey is the context key to store the JWT payload. Defaults to USER
PayloadContextKey string `mapstructure:"GOAUTH_JWKS_PAYLOAD_CONTEXT_KEY"`
}
// JWTConfig is the config to be used on the VerifyJWT handler
type JWTConfig struct {
// Header is the header to be used on the VerifyJWT handler. Defaults to Authorization
Header string `mapstructure:"GOAUTH_JWT_HEADER"`
// TokenType is the token type to be used on the VerifyJWT handler. Defaults to Bearer
TokenType string `mapstructure:"GOAUTH_JWT_TOKEN_TYPE"`
// SignatureKey is the signature key to be used on the VerifyJWT handler
SignatureKey string `mapstructure:"GOAUTH_JWT_SIGNATURE_KEY"`
// SignatureAlgorithm is the algorithm used to sign the JWT. Defaults to RS256
SignatureAlgorithm string `mapstructure:"GOAUTH_JWT_SIGNATURE_ALGORITHM"`
// PayloadContextKey is the context key to store the JWT payload. Defaults to USER
PayloadContextKey string `mapstructure:"GOAUTH_JWT_PAYLOAD_CONTEXT_KEY"`
}
// Config stores the configuration for the Goauth middleware
type Config struct {
// AuthHandlers is the list of authentication handlers to be used
Handlers []string `mapstructure:"GOAUTH_HANDLERS"`
// APIKeyConfig stores the configuration for the VerifyAPIKey handler
APIKeyConfig APIKeyConfig `mapstructure:",squash"`
// JWKSConfig stores the configuration for the VerifyJWKS handler
JWKSConfig JWKSConfig `mapstructure:",squash"`
// JWTConfig stores the configuration for the VerifyJWT handler
JWTConfig JWTConfig `mapstructure:",squash"`
}
var config = &Config{}
// LoadConfig loads the configuration from the environment variables
func loadConfig() {
viper.AutomaticEnv()
viper.SetDefault("GOAUTH_HANDLERS", []string{})
viper.SetDefault("GOAUTH_API_KEY_HEADER", "X-API-Key")
viper.SetDefault("GOAUTH_API_KEY_LIST", []string{})
viper.SetDefault("GOAUTH_JWKS_HEADER", "Authorization")
viper.SetDefault("GOAUTH_JWKS_TOKEN_TYPE", "Bearer")
viper.SetDefault("GOAUTH_JWKS_URL", "")
viper.SetDefault("GOAUTH_JWKS_REFRESH_WINDOW", 1*time.Minute)
viper.SetDefault("GOAUTH_JWKS_MIN_REFRESH_INTERVAL", 5*time.Minute)
viper.SetDefault("GOAUTH_JWKS_PAYLOAD_CONTEXT_KEY", "USER")
viper.SetDefault("GOAUTH_JWT_HEADER", "Authorization")
viper.SetDefault("GOAUTH_JWT_TOKEN_TYPE", "Bearer")
viper.SetDefault("GOAUTH_JWT_SIGNATURE_KEY", "")
viper.SetDefault("GOAUTH_JWT_SIGNATURE_ALGORITHM", "RS256")
viper.SetDefault("GOAUTH_JWT_PAYLOAD_CONTEXT_KEY", "USER")
viper.Unmarshal(config)
}
// BootstrapMiddleware sets up the authentication handlers.
// The context object is used to controll the life-cycle
// of the JWKS cache auto-refresh worker.
func BootstrapMiddleware(ctx context.Context) {
log.Log(log.Debug, "BootstrapMiddleware")
loadConfig()
if len(config.Handlers) == 0 {
return
}
log.Logf(log.Info, "Handlers: %s", config.Handlers)
handlers := []AuthHandler{}
for _, h := range config.Handlers {
switch strings.ToLower(h) {
case "api_key":
if len(config.APIKeyConfig.KeyList) == 0 {
log.Log(log.Panic, "GOAUTH_API_KEY_LIST is required when using the API Key handler")
}
cfg := handler.VerifyAPIKeyConfig{
Header: config.APIKeyConfig.Header,
Keys: config.APIKeyConfig.KeyList,
}
handlers = append(handlers, handler.NewVerifyAPIKey(cfg))
log.Log(log.Info, "Using API Key authentication")
case "jwks":
if config.JWKSConfig.URL == "" {
log.Log(log.Panic, "GOAUTH_JWKS_URL is required when using the JWKS handler")
}
cfg := handler.VerifyJWKSConfig{
Header: config.JWKSConfig.Header,
TokenType: config.JWKSConfig.TokenType,
URL: config.JWKSConfig.URL,
CacheConfig: handler.CacheConfig{
RefreshWindow: time.Duration(config.JWKSConfig.RefreshWindow),
MinRefreshInterval: time.Duration(config.JWKSConfig.MinRefreshInterval),
Context: ctx,
},
}
handlers = append(handlers, handler.NewVerifyJWKS(cfg))
log.Log(log.Info, "Using JWKS authentication")
case "jwt":
if config.JWTConfig.SignatureKey == "" {
log.Log(log.Panic, "GOAUTH_JWT_SIGNATURE_KEY is required when using the JWT handler")
}
cfg := handler.VerifyJWTConfig{
Header: config.JWTConfig.Header,
TokenType: config.JWTConfig.TokenType,
SignatureKey: config.JWTConfig.SignatureKey,
SignatureAlgorithm: config.JWTConfig.SignatureAlgorithm,
PayloadContextKey: config.JWTConfig.PayloadContextKey,
}
handlers = append(handlers, handler.NewVerifyJWT(cfg))
log.Log(log.Info, "Using JWT authentication")
}
}
SetHandlers(handlers)
}