@@ -229,8 +229,9 @@ func TestIsValidRedirect(t *testing.T) {
229229
230230type TestProvider struct {
231231 *providers.ProviderData
232− EmailAddress string
233− ValidToken bool
232+ EmailAddress string
233+ ValidToken bool
234+ GroupValidator func(string) bool
234235}
235236
236237func NewTestProvider(providerURL *url.URL, emailAddress string) *TestProvider {
@@ -255,6 +256,9 @@ func NewTestProvider(providerURL *url.URL, emailAddress string) *TestProvider {
255256 Scope: "profile.email",
256257 },
257258 EmailAddress: emailAddress,
259+ GroupValidator: func(s string) bool {
260+ return true
261+ },
258262 }
259263}
260264
@@ -266,6 +270,13 @@ func (tp *TestProvider) ValidateSessionState(session *sessions.SessionState) boo
266270 return tp.ValidToken
267271}
268272
273+func (tp *TestProvider) ValidateGroup(email string) bool {
274+ if tp.GroupValidator != nil {
275+ return tp.GroupValidator(email)
276+ }
277+ return true
278+}
279+
269280func TestBasicAuthPassword(t *testing.T) {
270281 providerServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
271282 logger.Printf("%#v", r)
@@ -791,6 +802,25 @@ func TestAuthOnlyEndpointUnauthorizedOnEmailValidationFailure(t *testing.T) {
791802 assert.Equal(t, "unauthorized request\n", string(bodyBytes))
792803}
793804
805+func TestAuthOnlyEndpointUnauthorizedOnProviderGroupValidationFailure(t *testing.T) {
806+ test := NewAuthOnlyEndpointTest()
807+ startSession := &sessions.SessionState{
808+ Email: "michael.bland@gsa.gov", AccessToken: "my_access_token", CreatedAt: time.Now()}
809+ test.SaveSession(startSession)
810+ provider := &TestProvider{
811+ ValidToken: true,
812+ GroupValidator: func(s string) bool {
813+ return false
814+ },
815+ }
816+
817+ test.proxy.provider = provider
818+ test.proxy.ServeHTTP(test.rw, test.req)
819+ assert.Equal(t, http.StatusUnauthorized, test.rw.Code)
820+ bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
821+ assert.Equal(t, "unauthorized request\n", string(bodyBytes))
822+}
823+
794824func TestAuthOnlyEndpointSetXAuthRequestHeaders(t *testing.T) {
795825 var pcTest ProcessCookieTest
796826
@@ -1168,69 +1198,80 @@ func TestGetJwtSession(t *testing.T) {
11681198 keyset := NoOpKeySet{}
11691199 verifier := oidc.NewVerifier("https://issuer.example.com", keyset,
11701200 &oidc.Config{ClientID: "https://test.myapp.com", SkipExpiryCheck: true})
1171− p := OAuthProxy{}
1172− p.jwtBearerVerifiers = append(p.jwtBearerVerifiers, verifier)
11731201
1174− req, _ := http.NewRequest("GET", "/", strings.NewReader(""))
1202+ test := NewAuthOnlyEndpointTest(func(opts *Options) {
1203+ opts.PassAuthorization = true
1204+ opts.SetAuthorization = true
1205+ opts.SetXAuthRequest = true
1206+ opts.SkipJwtBearerTokens = true
1207+ opts.jwtBearerVerifiers = append(opts.jwtBearerVerifiers, verifier)
1208+ })
1209+ tp, _ := test.proxy.provider.(*TestProvider)
1210+ tp.GroupValidator = func(s string) bool {
1211+ return true
1212+ }
1213+
11751214 authHeader := fmt.Sprintf("Bearer %s", goodJwt)
1176− req.Header = map[string][]string{
1215+ test.req.Header = map[string][]string{
11771216 "Authorization": {authHeader},
11781217 }
11791218
11801219 // Bearer
1181− session, _ := p.GetJwtSession(req)
1220+ session, _ := test.proxy.GetJwtSession(test.req)
11821221 assert.Equal(t, session.User, "john@example.com")
11831222 assert.Equal(t, session.Email, "john@example.com")
11841223 assert.Equal(t, session.ExpiresOn, time.Unix(1912151821, 0))
11851224 assert.Equal(t, session.IDToken, goodJwt)
11861225
1187− jwtProviderServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1188− logger.Printf("%#v", r)
1189− var payload string
1190− payload = r.Header.Get("Authorization")
1191− if payload == "" {
1192− payload = "No Authorization header found."
1193− }
1194− w.WriteHeader(200)
1195− w.Write([]byte(payload))
1196− }))
1226+ test.proxy.ServeHTTP(test.rw, test.req)
1227+ if test.rw.Code >= 400 {
1228+ t.Fatalf("expected 3xx got %d", test.rw.Code)
1229+ }
11971230
1198− opts := NewOptions()
1199− opts.Upstreams = append(opts.Upstreams, jwtProviderServer.URL)
1200− opts.PassAuthorization = true
1201− opts.SetAuthorization = true
1202− opts.SetXAuthRequest = true
1203− opts.CookieSecret = "0123456789abcdef0123"
1204− opts.SkipJwtBearerTokens = true
1205− opts.Validate()
1231+ // Check PassAuthorization, should overwrite Basic header
1232+ assert.Equal(t, test.req.Header.Get("Authorization"), authHeader)
1233+ assert.Equal(t, test.req.Header.Get("X-Forwarded-User"), "john@example.com")
1234+ assert.Equal(t, test.req.Header.Get("X-Forwarded-Email"), "john@example.com")
12061235
1207− // We can't actually use opts.Validate() because it will attempt to find a jwks URI
1208− opts.jwtBearerVerifiers = append(opts.jwtBearerVerifiers, verifier)
1236+ // SetAuthorization and SetXAuthRequest
1237+ assert.Equal(t, test.rw.Header().Get("Authorization"), authHeader)
1238+ assert.Equal(t, test.rw.Header().Get("X-Auth-Request-User"), "john@example.com")
1239+ assert.Equal(t, test.rw.Header().Get("X-Auth-Request-Email"), "john@example.com")
1240+}
12091241
1210− providerURL, _ := url.Parse(jwtProviderServer.URL)
1211− const emailAddress = "john@example.com"
1242+func TestJwtUnauthorizedOnGroupValidationFailure(t *testing.T) {
1243+ goodJwt := "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9." +
1244+ "eyJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjoiaHR0cHM6Ly90ZXN0Lm15YXBwLmNvbSIsIm5hbWUiOiJKb2huIERvZSIsImVtY" +
1245+ "WlsIjoiam9obkBleGFtcGxlLmNvbSIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwiaWF0IjoxNTUzNjkxMj" +
1246+ "E1LCJleHAiOjE5MTIxNTE4MjF9." +
1247+ "rLVyzOnEldUq_pNkfa-WiV8TVJYWyZCaM2Am_uo8FGg11zD7l-qmz3x1seTvqpH6Y0Ty00fmv6dJnGnC8WMnPXQiodRTfhBSe" +
1248+ "OKZMu0HkMD2sg52zlKkbfLTO6ic5VnbVgwjjrB8am_Ta6w7kyFUaB5C1BsIrrLMldkWEhynbb8"
12121249
1213− opts.provider = NewTestProvider(providerURL, emailAddress)
1214− jwtTestProxy := NewOAuthProxy(opts, func(email string) bool {
1215− return email == emailAddress
1216− })
1250+ keyset := NoOpKeySet{}
1251+ verifier := oidc.NewVerifier("https://issuer.example.com", keyset,
1252+ &oidc.Config{ClientID: "https://test.myapp.com", SkipExpiryCheck: true})
12171253
1218− rw := httptest.NewRecorder()
1219− jwtTestProxy.ServeHTTP(rw, req)
1220− if rw.Code >= 400 {
1221− t.Fatalf("expected 3xx got %d", rw.Code)
1254+ test := NewAuthOnlyEndpointTest(func(opts *Options) {
1255+ opts.PassAuthorization = true
1256+ opts.SetAuthorization = true
1257+ opts.SetXAuthRequest = true
1258+ opts.SkipJwtBearerTokens = true
1259+ opts.jwtBearerVerifiers = append(opts.jwtBearerVerifiers, verifier)
1260+ })
1261+ tp, _ := test.proxy.provider.(*TestProvider)
1262+ // Verify ValidateGroup fails JWT authorization
1263+ tp.GroupValidator = func(s string) bool {
1264+ return false
12221265 }
12231266
1224− // Check PassAuthorization, should overwrite Basic header
1225− assert.Equal(t, req.Header.Get("Authorization"), authHeader)
1226− assert.Equal(t, req.Header.Get("X-Forwarded-User"), "john@example.com")
1227− assert.Equal(t, req.Header.Get("X-Forwarded-Email"), "john@example.com")
1228−
1229− // SetAuthorization and SetXAuthRequest
1230− assert.Equal(t, rw.Header().Get("Authorization"), authHeader)
1231− assert.Equal(t, rw.Header().Get("X-Auth-Request-User"), "john@example.com")
1232− assert.Equal(t, rw.Header().Get("X-Auth-Request-Email"), "john@example.com")
1233−
1267+ authHeader := fmt.Sprintf("Bearer %s", goodJwt)
1268+ test.req.Header = map[string][]string{
1269+ "Authorization": {authHeader},
1270+ }
1271+ test.proxy.ServeHTTP(test.rw, test.req)
1272+ if test.rw.Code != http.StatusUnauthorized {
1273+ t.Fatalf("expected 401 got %d", test.rw.Code)
1274+ }
12341275}
12351276
12361277func TestFindJwtBearerToken(t *testing.T) {