Browse Source

fix: Add optional Nonce parameter to the authorization URL requests (#606)

* feat: add optional nonce parameter to the authorization URL requests

* fix: shorten docstring to be below max line length

---------

Co-authored-by: Greg Griffin <greg@lapetussolutions.com>
master v4.6.3
gregriff 6 days ago
committed by GitHub
parent
commit
0c52ec4142
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 10
      src/keycloak/keycloak_openid.py
  2. 2
      src/keycloak/urls_patterns.py
  3. 4
      tests/test_keycloak_openid.py

10
src/keycloak/keycloak_openid.py

@ -257,7 +257,7 @@ class KeycloakOpenID:
data_raw = self.connection.raw_get(URL_WELL_KNOWN.format(**params_path)) data_raw = self.connection.raw_get(URL_WELL_KNOWN.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError) return raise_error_from_response(data_raw, KeycloakGetError)
def auth_url(self, redirect_uri, scope="email", state=""):
def auth_url(self, redirect_uri, scope="email", state="", nonce=""):
"""Get authorization URL endpoint. """Get authorization URL endpoint.
:param redirect_uri: Redirect url to receive oauth code :param redirect_uri: Redirect url to receive oauth code
@ -266,6 +266,8 @@ class KeycloakOpenID:
:type scope: str :type scope: str
:param state: State will be returned to the redirect_uri :param state: State will be returned to the redirect_uri
:type state: str :type state: str
:param nonce: Associates a Client session with an ID Token to mitigate replay attacks
:type nonce: str
:returns: Authorization URL Full Build :returns: Authorization URL Full Build
:rtype: str :rtype: str
""" """
@ -275,6 +277,7 @@ class KeycloakOpenID:
"redirect-uri": redirect_uri, "redirect-uri": redirect_uri,
"scope": scope, "scope": scope,
"state": state, "state": state,
"nonce": nonce,
} }
return URL_AUTH.format(**params_path) return URL_AUTH.format(**params_path)
@ -903,7 +906,7 @@ class KeycloakOpenID:
data_raw = await self.connection.a_raw_get(URL_WELL_KNOWN.format(**params_path)) data_raw = await self.connection.a_raw_get(URL_WELL_KNOWN.format(**params_path))
return raise_error_from_response(data_raw, KeycloakGetError) return raise_error_from_response(data_raw, KeycloakGetError)
async def a_auth_url(self, redirect_uri, scope="email", state=""):
async def a_auth_url(self, redirect_uri, scope="email", state="", nonce=""):
"""Get authorization URL endpoint asynchronously. """Get authorization URL endpoint asynchronously.
:param redirect_uri: Redirect url to receive oauth code :param redirect_uri: Redirect url to receive oauth code
@ -912,6 +915,8 @@ class KeycloakOpenID:
:type scope: str :type scope: str
:param state: State will be returned to the redirect_uri :param state: State will be returned to the redirect_uri
:type state: str :type state: str
:param nonce: Associates a Client session with an ID Token to mitigate replay attacks
:type nonce: str
:returns: Authorization URL Full Build :returns: Authorization URL Full Build
:rtype: str :rtype: str
""" """
@ -921,6 +926,7 @@ class KeycloakOpenID:
"redirect-uri": redirect_uri, "redirect-uri": redirect_uri,
"scope": scope, "scope": scope,
"state": state, "state": state,
"nonce": nonce,
} }
return URL_AUTH.format(**params_path) return URL_AUTH.format(**params_path)

2
src/keycloak/urls_patterns.py

@ -35,7 +35,7 @@ URL_INTROSPECT = "realms/{realm-name}/protocol/openid-connect/token/introspect"
URL_ENTITLEMENT = "realms/{realm-name}/authz/entitlement/{resource-server-id}" URL_ENTITLEMENT = "realms/{realm-name}/authz/entitlement/{resource-server-id}"
URL_AUTH = ( URL_AUTH = (
"{authorization-endpoint}?client_id={client-id}&response_type=code&redirect_uri={redirect-uri}" "{authorization-endpoint}?client_id={client-id}&response_type=code&redirect_uri={redirect-uri}"
"&scope={scope}&state={state}"
"&scope={scope}&state={state}&nonce={nonce}"
) )
URL_DEVICE = "realms/{realm-name}/protocol/openid-connect/auth/device" URL_DEVICE = "realms/{realm-name}/protocol/openid-connect/auth/device"

4
tests/test_keycloak_openid.py

@ -121,7 +121,7 @@ def test_auth_url(env, oid: KeycloakOpenID):
res res
== f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}/realms/{oid.realm_name}" == f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}/realms/{oid.realm_name}"
+ f"/protocol/openid-connect/auth?client_id={oid.client_id}&response_type=code" + f"/protocol/openid-connect/auth?client_id={oid.client_id}&response_type=code"
+ "&redirect_uri=http://test.test/*&scope=email&state="
+ "&redirect_uri=http://test.test/*&scope=email&state=&nonce="
) )
@ -575,7 +575,7 @@ async def test_a_auth_url(env, oid: KeycloakOpenID):
res res
== f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}/realms/{oid.realm_name}" == f"http://{env.KEYCLOAK_HOST}:{env.KEYCLOAK_PORT}/realms/{oid.realm_name}"
+ f"/protocol/openid-connect/auth?client_id={oid.client_id}&response_type=code" + f"/protocol/openid-connect/auth?client_id={oid.client_id}&response_type=code"
+ "&redirect_uri=http://test.test/*&scope=email&state="
+ "&redirect_uri=http://test.test/*&scope=email&state=&nonce="
) )

Loading…
Cancel
Save