Skip to content

Commit

Permalink
fix(hmac): add missing www-authenticate headers
Browse files Browse the repository at this point in the history
When server returns 401 Unauthorized response it should
return WWW-Authenticate header as well with proper challenge.
HMAC auth was missing this header.

Fix: #7772
KAG-321
  • Loading branch information
nowNick committed Feb 15, 2024
1 parent ed3d905 commit 150a3e4
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 24 deletions.
3 changes: 3 additions & 0 deletions changelog/unreleased/kong/hmac_www_authenticate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
message: Add WWW-Authenticate headers to 401 response in hmac auth plugin.
type: bugfix
scope: Plugin
25 changes: 15 additions & 10 deletions kong/plugins/hmac-auth/access.lua
Original file line number Diff line number Diff line change
Expand Up @@ -275,24 +275,29 @@ local function set_consumer(consumer, credential)
end
end

local function unauthorized(message, www_auth_content)
return { status = 401, message = message, headers = { ["WWW-Authenticate"] = www_auth_content } }
end


local function do_authentication(conf)
local authorization = kong_request.get_header(AUTHORIZATION)
local proxy_authorization = kong_request.get_header(PROXY_AUTHORIZATION)
local www_auth_content = conf.realm and fmt('hmac realm="%s"', conf.realm) or 'hmac'

-- If both headers are missing, return 401
if not (authorization or proxy_authorization) then
return false, { status = 401, message = "Unauthorized" }
return false, unauthorized("Unauthorized", www_auth_content)
end

-- validate clock skew
if not (validate_clock_skew(X_DATE, conf.clock_skew) or
validate_clock_skew(DATE, conf.clock_skew)) then
return false, {
status = 401,
message = "HMAC signature cannot be verified, a valid date or " ..
"x-date header is required for HMAC Authentication"
}
return false, unauthorized(
"HMAC signature cannot be verified, a valid date or " ..
"x-date header is required for HMAC Authentication",
www_auth_content
)
end

-- retrieve hmac parameter from Proxy-Authorization header
Expand All @@ -312,26 +317,26 @@ local function do_authentication(conf)
local ok, err = validate_params(hmac_params, conf)
if not ok then
kong.log.debug(err)
return false, { status = 401, message = SIGNATURE_NOT_VALID }
return false, unauthorized(SIGNATURE_NOT_VALID, www_auth_content)
end

-- validate signature
local credential = load_credential(hmac_params.username)
if not credential then
kong.log.debug("failed to retrieve credential for ", hmac_params.username)
return false, { status = 401, message = SIGNATURE_NOT_VALID }
return false, unauthorized(SIGNATURE_NOT_VALID, www_auth_content)
end

hmac_params.secret = credential.secret

if not validate_signature(hmac_params) then
return false, { status = 401, message = SIGNATURE_NOT_SAME }
return false, unauthorized(SIGNATURE_NOT_SAME, www_auth_content)
end

-- If request body validation is enabled, then verify digest.
if conf.validate_request_body and not validate_body() then
kong.log.debug("digest validation failed")
return false, { status = 401, message = SIGNATURE_NOT_SAME }
return false, unauthorized(SIGNATURE_NOT_SAME, www_auth_content)
end

-- Retrieve consumer
Expand Down
5 changes: 5 additions & 0 deletions kong/plugins/hmac-auth/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ return {
elements = { type = "string", one_of = ALGORITHMS },
default = ALGORITHMS,
}, },
{ realm = {
description = "When authentication or authorization fails, or there is an unexpected error, the plugin sends an `WWW-Authenticate` header with the `realm` attribute value.",
type = "string",
required = false
}, },
},
},
},
Expand Down
Loading

0 comments on commit 150a3e4

Please sign in to comment.