Fix several problems in keycloak auth module
1. Instead of 'realm_name' and 'password' the module gets 'project_name' and 'api_key' respectively. 2. Dictionary with 'auth_token' key should be returned, not just a string with a token. 3. Client secret is an optional parameter and shouldn't be required during authentication. Closes-bug: #1719560 Change-Id: I886480b9aaec8493039ff83e114b8183a0f5fddc
This commit is contained in:
parent
d691ab2169
commit
e4057bb358
@ -38,10 +38,10 @@ class KeycloakAuthHandler(auth.AuthHandler):
|
|||||||
* client_id: Client ID (according to OpenID Connect protocol).
|
* client_id: Client ID (according to OpenID Connect protocol).
|
||||||
* client_secret: Client secret (according to OpenID Connect
|
* client_secret: Client secret (according to OpenID Connect
|
||||||
protocol).
|
protocol).
|
||||||
* realm_name: KeyCloak realm name.
|
* project_name: KeyCloak realm name.
|
||||||
* username: User name (Optional, if None then access_token must be
|
* username: User name (Optional, if None then access_token must be
|
||||||
provided).
|
provided).
|
||||||
* password: Password (Optional).
|
* api_key: Password (Optional).
|
||||||
* access_token: Access token. If passed, username and password are
|
* access_token: Access token. If passed, username and password are
|
||||||
not used and this method just validates the token and refreshes
|
not used and this method just validates the token and refreshes
|
||||||
it if needed (Optional, if None then username must be
|
it if needed (Optional, if None then username must be
|
||||||
@ -59,9 +59,9 @@ class KeycloakAuthHandler(auth.AuthHandler):
|
|||||||
auth_url = req.get('auth_url')
|
auth_url = req.get('auth_url')
|
||||||
client_id = req.get('client_id')
|
client_id = req.get('client_id')
|
||||||
client_secret = req.get('client_secret')
|
client_secret = req.get('client_secret')
|
||||||
realm_name = req.get('realm_name')
|
realm_name = req.get('project_name')
|
||||||
username = req.get('username')
|
username = req.get('username')
|
||||||
password = req.get('password')
|
password = req.get('api_key')
|
||||||
access_token = req.get('access_token')
|
access_token = req.get('access_token')
|
||||||
cacert = req.get('cacert')
|
cacert = req.get('cacert')
|
||||||
insecure = req.get('insecure', False)
|
insecure = req.get('insecure', False)
|
||||||
@ -72,9 +72,6 @@ class KeycloakAuthHandler(auth.AuthHandler):
|
|||||||
if not client_id:
|
if not client_id:
|
||||||
raise ValueError('Client ID is not provided.')
|
raise ValueError('Client ID is not provided.')
|
||||||
|
|
||||||
if not client_secret:
|
|
||||||
raise ValueError('Client secret is not provided.')
|
|
||||||
|
|
||||||
if not realm_name:
|
if not realm_name:
|
||||||
raise ValueError('Project(realm) name is not provided.')
|
raise ValueError('Project(realm) name is not provided.')
|
||||||
|
|
||||||
@ -110,9 +107,7 @@ class KeycloakAuthHandler(auth.AuthHandler):
|
|||||||
insecure
|
insecure
|
||||||
)
|
)
|
||||||
|
|
||||||
response['project_id'] = realm_name
|
return {'auth_token': response, 'project_id': realm_name}
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _authenticate_with_token(auth_url, client_id, client_secret,
|
def _authenticate_with_token(auth_url, client_id, client_secret,
|
||||||
@ -131,20 +126,21 @@ class KeycloakAuthHandler(auth.AuthHandler):
|
|||||||
|
|
||||||
verify = None
|
verify = None
|
||||||
if urllib.parse.urlparse(access_token_endpoint).scheme == "https":
|
if urllib.parse.urlparse(access_token_endpoint).scheme == "https":
|
||||||
verify = False if insecure else cacert
|
verify = False if insecure else cacert if cacert else True
|
||||||
|
|
||||||
client_auth = (client_id, client_secret)
|
|
||||||
|
|
||||||
body = {
|
body = {
|
||||||
'grant_type': 'password',
|
'grant_type': 'password',
|
||||||
'username': username,
|
'username': username,
|
||||||
'password': password,
|
'password': password,
|
||||||
|
'client_id': client_id,
|
||||||
'scope': 'profile'
|
'scope': 'profile'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if client_secret:
|
||||||
|
body['client_secret'] = client_secret,
|
||||||
|
|
||||||
resp = requests.post(
|
resp = requests.post(
|
||||||
access_token_endpoint,
|
access_token_endpoint,
|
||||||
auth=client_auth,
|
|
||||||
data=body,
|
data=body,
|
||||||
verify=verify
|
verify=verify
|
||||||
)
|
)
|
||||||
@ -177,6 +173,10 @@ def get_system_ca_file():
|
|||||||
return ca
|
return ca
|
||||||
LOG.warning("System ca file could not be found.")
|
LOG.warning("System ca file could not be found.")
|
||||||
|
|
||||||
|
# An example of working curl request to keycloak
|
||||||
|
# curl -d "client_id=admin-cli" -d "client_secret=secret"
|
||||||
|
# -d "username=admin" -d "password=qwerty" -d "grant_type=password"
|
||||||
|
# "http://localhost:8080/auth/realms/master/protocol/openid-connect/token"
|
||||||
|
|
||||||
# An example of using KeyCloak OpenID authentication.
|
# An example of using KeyCloak OpenID authentication.
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
@ -188,12 +188,12 @@ if __name__ == '__main__':
|
|||||||
dict(
|
dict(
|
||||||
"https://my.keycloak:8443/auth",
|
"https://my.keycloak:8443/auth",
|
||||||
client_id="mistral_client",
|
client_id="mistral_client",
|
||||||
client_secret="4a080907-921b-409a-b793-c431609c3a47",
|
client_secret="secret",
|
||||||
realm_name="mistral",
|
project_name="mistral",
|
||||||
username="user",
|
username="user",
|
||||||
password="secret",
|
api_key="secret",
|
||||||
insecure=True
|
insecure=True
|
||||||
)
|
)
|
||||||
)
|
)['auth_token']
|
||||||
|
|
||||||
print("Access token: %s" % a_token)
|
print("Auth token: %s" % a_token)
|
||||||
|
Loading…
Reference in New Issue
Block a user