I’ve looked at the code and found the following:
HammerCLIForeman::OpenidConnect connects to the IDP (Keycloak in my case) to exchange the authorization_code for a valid JWT token. This token would be passed to Foreman afterwards.
However, the request to the IDP fails here: https://github.com/theforeman/hammer-cli-foreman/blob/master/lib/hammer_cli_foreman/openid_connect.rb#L45-L53 with
[18] pry(#<HammerCLIForeman::OpenidConnect>)> response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |https|
https.request(request)
=> #<Net::HTTPUnauthorized 401 Unauthorized readbody=true>
[19] pry(#<HammerCLIForeman::OpenidConnect>)> response.body
=> "{\"error\":\"unauthorized_client\",\"error_description\":\"Client secret not provided in request\"}"
which makes sense as the client_secret should be private and only present on the foreman server (mod_auth_openidc module configuration) if the access type is set to confidential
(see screenshot):
This means:
- If used with
confidential
a client would need to send a valid authorization_code, client_id AND client_secret in order to exchange the authorization_code for a valid token - If used with
public
a client would only need to send the authorization_code and the client_id to get the token
And I can confirm, that both ways work if I either set access type to public
or provide the client_secret
as part of the hammer request.
Based on that, I have two questions/proposals:
- Hammer should display such failed requests to the IDP to the user. If the response body is show, it is quite obvious where the problem lays
- if access type needs to be configured to
public
we should document this askeycloak-httpd-client-install
does not provide the needed config options. However, I still need to look into the implications of setting the access type topublic
!