JWT: Allow conventional bearer token in Authorization header (#54821)

* fix: allow JWT to accept standard bearer token

* fix: linter issues

* fix: linter gosec false positive

* fix: refactor logic into JWT handler

* fix: move bearer trimming earlier
This commit is contained in:
Nicholas Wiersma
2022-09-09 11:05:58 +02:00
committed by GitHub
parent 366129c14e
commit faf8eb3afb
4 changed files with 67 additions and 1 deletions

View File

@@ -24,6 +24,11 @@ func TestMiddlewareJWTAuth(t *testing.T) {
cfg.JWTAuthHeaderName = "x-jwt-assertion"
}
configureAuthHeader := func(cfg *setting.Cfg) {
cfg.JWTAuthEnabled = true
cfg.JWTAuthHeaderName = "Authorization"
}
configureUsernameClaim := func(cfg *setting.Cfg) {
cfg.JWTAuthUsernameClaim = "foo-username"
}
@@ -72,6 +77,30 @@ func TestMiddlewareJWTAuth(t *testing.T) {
assert.Equal(t, myUsername, sc.context.Login)
}, configure, configureUsernameClaim)
middlewareScenario(t, "Valid token with bearer in authorization header", func(t *testing.T, sc *scenarioContext) {
myUsername := "vladimir"
// We can ignore gosec G101 since this does not contain any credentials.
// nolint:gosec
myToken := "some.jwt.token"
var verifiedToken string
sc.jwtAuthService.VerifyProvider = func(ctx context.Context, token string) (models.JWTClaims, error) {
verifiedToken = myToken
return models.JWTClaims{
"sub": myUsername,
"foo-username": myUsername,
}, nil
}
sc.userService.ExpectedSignedInUser = &user.SignedInUser{UserID: id, OrgID: orgID, Login: myUsername}
sc.fakeReq("GET", "/").withJWTAuthHeader("Bearer " + myToken).exec()
assert.Equal(t, verifiedToken, myToken)
assert.Equal(t, 200, sc.resp.Code)
assert.True(t, sc.context.IsSignedIn)
assert.Equal(t, orgID, sc.context.OrgID)
assert.Equal(t, id, sc.context.UserID)
assert.Equal(t, myUsername, sc.context.Login)
}, configureAuthHeader, configureUsernameClaim)
middlewareScenario(t, "Valid token with valid email claim", func(t *testing.T, sc *scenarioContext) {
var verifiedToken string
sc.jwtAuthService.VerifyProvider = func(ctx context.Context, token string) (models.JWTClaims, error) {

View File

@@ -81,6 +81,11 @@ func TestMiddleWareSecurityHeaders(t *testing.T) {
func TestMiddlewareContext(t *testing.T) {
const noCache = "no-cache"
configureJWTAuthHeader := func(cfg *setting.Cfg) {
cfg.JWTAuthEnabled = true
cfg.JWTAuthHeaderName = "Authorization"
}
middlewareScenario(t, "middleware should add context to injector", func(t *testing.T, sc *scenarioContext) {
sc.fakeReq("GET", "/").exec()
assert.NotNil(t, sc.context)
@@ -165,6 +170,22 @@ func TestMiddlewareContext(t *testing.T) {
assert.Equal(t, org.RoleEditor, sc.context.OrgRole)
})
middlewareScenario(t, "Valid API key with JWT enabled", func(t *testing.T, sc *scenarioContext) {
const orgID int64 = 12
keyhash, err := util.EncodePassword("v5nAwpMafFP6znaS4urhdWDLS5511M42", "asd")
require.NoError(t, err)
sc.apiKeyService.ExpectedAPIKey = &apikey.APIKey{OrgId: orgID, Role: org.RoleEditor, Key: keyhash}
sc.fakeReq("GET", "/").withValidApiKey().exec()
require.Equal(t, 200, sc.resp.Code)
assert.True(t, sc.context.IsSignedIn)
assert.Equal(t, orgID, sc.context.OrgID)
assert.Equal(t, org.RoleEditor, sc.context.OrgRole)
}, configureJWTAuthHeader)
middlewareScenario(t, "Valid API key, but does not match DB hash", func(t *testing.T, sc *scenarioContext) {
const keyhash = "Something_not_matching"
sc.apiKeyService.ExpectedAPIKey = &apikey.APIKey{OrgId: 12, Role: org.RoleEditor, Key: keyhash}