Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[keycloak] Accept client credentials for token endpoint in Authorization header #336

Merged
merged 2 commits into from
Mar 29, 2017

Conversation

mayorova
Copy link
Contributor

Close #319

@@ -248,7 +262,8 @@ function _M:get_token(service, client)
-- call Keycloak authorize
local url = self.config.token_url

local res = http_client.post(url, req_body)
local headers = ngx.req.get_headers()
local res = http_client.post(url, ngx.req.get_post_args(), { headers = headers })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any test covering why it should pass all request headers to the keycloak endpoint. Why it should do that? Shouldn't it be just some whitelist of headers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a test that verifies that headers are passed at all: https://github.com/3scale/apicast/pull/336/files/8cd98a1f55125a836cd94603cca2223460d0d716#diff-bc82c1966e003ef46c8dc5a71bb64c5d
Because they were not before, so the test would fail.
Now, regarding all headers VS whitelist, for now I really only need the Authorization header, but I am not sure if there can be some other headers that Keycloak may be expecting.
We can limit it to Authorization for now, and test that others are not proxy passed (although not sure how to do it with test backend).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test backend can just expect headers that are passed. Like

test_backend.expect{ url = 'http://example.com/t', headers = { ['User-Agent'] = tostring(user_agent) } }
        .respond_with{ status = 200  }

IMO we should limit what is sent to Keycloak according to the spec/documentation and not whatever client sends.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re: testing, yes, there is a test that checks the authorization header is passed (link, the previous one was not correct), but I don't know how to check that other headers were not passed. Could be an integration test, but maybe not so necessary?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think one positive test will be fine (checking that the Authorization is passed) and if we have to stub some method that returns a table then we can add some extra headers there and see that they are not in keycloak.

local creds = _M.get_client_credentials(params)

params.client_id = creds.client_id
params.client_secret = creds.client_secret
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why mutating and using params instead of using creds ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because token_check_params needs all params + credentials (if they are not in params, they should be taken from headers). Happy to try something different.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Well I guess it is fine for now and will be refactored when we will rewrite OAuth from scratch.

@mikz mikz added this to the On-premise CR1 release milestone Mar 27, 2017
-- currently only passing the Authorization header used for the client authentication
function _M.token_get_headers()
local auth = ngx.var.http_authorization
return auth and { ['Authorization'] = auth } or {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be the same:

return { ['Authorization'] = ngx.var.http_authorization }

Because { whatever = nil } is {}.

Copy link
Contributor

@mikz mikz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one small nitpick and it needs CHANGELOG entry.

[keycloak] Only pass Authorization header from client to Keycloak
@mikz mikz merged commit 8fcf2f5 into master Mar 29, 2017
@mikz mikz deleted the fix-keycloak-basic-auth branch March 29, 2017 06:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants