@@ -36,6 +36,8 @@ type Config struct {
3636
3737// ConfigWhitelist the middleware configuration whitelist.
3838type ConfigWhitelist struct {
39+ TwoFactorAuthRequired string `json:"two_factor_auth_required,omitempty"`
40+
3941 // Ids the GitHub user id list.
4042 Ids []string `json:"ids,omitempty"`
4143 // Logins the GitHub user login list.
@@ -53,9 +55,10 @@ func CreateConfig() *Config {
5355 AuthPath : DefaultConfigAuthPath ,
5456 JwtSecretKey : getRandomString32 (),
5557 Whitelist : ConfigWhitelist {
56- Ids : []string {},
57- Logins : []string {},
58- Teams : []string {},
58+ Ids : []string {},
59+ Logins : []string {},
60+ Teams : []string {},
61+ TwoFactorAuthRequired : "false" ,
5962 },
6063 }
6164}
@@ -66,13 +69,14 @@ type TraefikGithubOauthMiddleware struct {
6669 next http.Handler
6770 name string
6871
69- apiBaseUrl string
70- apiSecretKey string
71- authPath string
72- jwtSecretKey string
73- whitelistIdSet * strset.Set
74- whitelistLoginSet * strset.Set
75- whitelistTeamSet * strset.Set
72+ apiBaseUrl string
73+ apiSecretKey string
74+ authPath string
75+ jwtSecretKey string
76+ whitelistIdSet * strset.Set
77+ whitelistLoginSet * strset.Set
78+ whitelistTeamSet * strset.Set
79+ whitelistRequires2FA bool
7680
7781 logger * log.Logger
7882}
@@ -96,13 +100,14 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
96100 next : next ,
97101 name : name ,
98102
99- apiBaseUrl : baseUrl ,
100- apiSecretKey : config .ApiSecretKey ,
101- authPath : authPath ,
102- jwtSecretKey : config .JwtSecretKey ,
103- whitelistIdSet : strset .New (config .Whitelist .Ids ... ),
104- whitelistLoginSet : strset .New (config .Whitelist .Logins ... ),
105- whitelistTeamSet : strset .New (config .Whitelist .Teams ... ),
103+ apiBaseUrl : baseUrl ,
104+ apiSecretKey : config .ApiSecretKey ,
105+ authPath : authPath ,
106+ jwtSecretKey : config .JwtSecretKey ,
107+ whitelistIdSet : strset .New (config .Whitelist .Ids ... ),
108+ whitelistLoginSet : strset .New (config .Whitelist .Logins ... ),
109+ whitelistTeamSet : strset .New (config .Whitelist .Teams ... ),
110+ whitelistRequires2FA : config .Whitelist .TwoFactorAuthRequired == "true" ,
106111
107112 logger : logger ,
108113 }, nil
@@ -133,6 +138,13 @@ func (middleware *TraefikGithubOauthMiddleware) handleRequest(rw http.ResponseWr
133138 return
134139 }
135140
141+ // Early check for 2FA -- if user is not whitelisted and 2FA is required, return 401
142+ if middleware .whitelistRequires2FA && ! user .TwoFactorEnabled {
143+ setNoCacheHeaders (rw )
144+ http .Error (rw , "" , http .StatusUnauthorized )
145+ return
146+ }
147+
136148 // If cookie is present, check if user is whitelisted
137149 // If nothing can be found, returns 404 as we don't want to leak information
138150 // But we log the error internally
@@ -160,7 +172,13 @@ func (p TraefikGithubOauthMiddleware) handleAuthRequest(rw http.ResponseWriter,
160172 }
161173
162174 // Generate JWTs
163- tokenString , err := jwt .GenerateJwtTokenString (result .GitHubUserID , result .GitHubUserLogin , result .GithubTeamIDs , p .jwtSecretKey )
175+ tokenString , err := jwt .GenerateJwtTokenString (
176+ result .GitHubUserID ,
177+ result .GitHubUserLogin ,
178+ result .GithubTeamIDs ,
179+ p .jwtSecretKey ,
180+ p .whitelistRequires2FA ,
181+ )
164182 if err != nil {
165183 p .logger .Printf ("Failed to generate JWT: %s" , err .Error ())
166184 http .Error (rw , "" , http .StatusInternalServerError )
0 commit comments