This sample python application acts as a wrapper of 3Scale's Red Hat SSO integration with OpenID Connect. It translates incoming requests to RESTCONF which is used by Curity's configuration admin API.
3Scale communicates with an OpenID provider using one of two proprietary ways:
- Rest API (unsupported by this repository)
- Red Hat SSO, using the ClientRepresentation found here (supported by this repository)
Both these ways use the OpenID Issuer as base url. Since Curity's Rest API is served under another port than the OpenID Server, we would need to proxy those requests to the RESTCONF API.
This can be done using several techniques, as an example, we ll use nginx. So the full picture will look like this:
+------------+ +------------+
| 3Scale | -------- > | Nginx | -------------------
+------------+ +------------+ |
8443 | | 8443 (<issuer>/clients-registrations)
| |
↓ ↓
+------------+ 6749 +-------------+
| Curity | < -------- | Wrapper |
+------------+ +-------------+
The Ngnix configuration for this example looks like this:
location /~/clients-registrations/default {
proxy_pass "http://<wrapper_host>:5555";
}
location / {
proxy_pass "https://<curity_ip>:<curity_port>";
}
First, install the requirements pip install -r requirements.txt
Edit the server.py file and configure the corresponding values in the config section:
restconf_api_host = "https://localhost:6749" # Admin API base url
restconf_api_username = "admin" # Admin user username
restconf_api_password = "Password1" # Admin user password
introspection_host = "http://localhost:8443" # Curity base URL
oauth_profile_id = "authorization" # Name of the Token Profile
default_scopes = "read write" # Default scopes in a space separated string(can be empty)
allowed_authenticators = "html1 bankid" # Allowed authenticators in a space separated string(can be empty)
issuer_path = "/~" # Curity's oauth-anonymous endpoint path
introspection_path = "/oauth/v2/oauth-introspect" # Curity's introspection endpoint path
introspection_client_id = "3scale_rest_api_wrapper" # Client ID for introspection
introspection_client_secret = "Password2" # Client secret
verify_ssl = True # Verify ssl certificate for introspection and RESTCONF API
debug = False # Run in debug mode
The client configured in this section must be allowed to do introspection.
Another client will be needed, that can do client_credentials. This second client will be used by 3Scale to get an access token for further communication with this wrapper.
Alternatively, the following environment variables can be set (i.e in a container environment):
- ADMIN_API_BASE_URL
- ADMIN_API_USERNAME
- ADMIN_API_PASSWORD
- CURITY_BASE_URL
- OAUTH_PROFILE_ID
- SCOPES
- ALLOWED_AUTHENTICATORS
- CURITY_TOKEN_ANONYMOUS_PATH
- CURITY_INTROSPECTION_PATH
- INTROSPECTION_CLIENT_ID
- INTROSPECTION_CLIENT_SECRET
- VERIFY_SSL
- DEBUG
- Curity's Base URL has to be the one that nginx proxies (configure it under System/General)
- Create 2 clients, one for introspection which is configured in the python app and one with client_credentials which is configured in 3Scale
- Change the token endpoint path to be
<issuer>/token_endpoint
this is because currently there is a bug in 3Scale where the token_endpoint is not properly read from the openid-metadata
In order to be able to issue tokens for applications created in 3Scale, the access tokens have to be in JWT format. To enable this, set the flag "Use Access Token As JWT" in the Token Profile/Token Issuers page.
- Create/Update a client
3Scale calls <openid_issuer>/clients-registrations/default/<client_id>
This is translated to a PUT to
http(s)://<curity_host>:<admin_port>/admin/api/restconf/data/base:profiles/base:profile=<token_profile_id>,oauth-service/base:settings/profile-oauth:authorization-server/profile-oauth:client-store/profile-oauth:config-backed/client=<client_id>"
Keep in mind that the clients created have a basic configuration (i.e. no authenticator-filters, template-areas etc), so if you need to add more specific configuration you can modify the corresponding JSON Object as needed in server.py
.
- Delete a client
3Scale calls <openid_issuer>/clients-registrations/default/<client_id>
with HTTP DELETE.
This is translated to a DELETE request on Curity's RESTCONF API.
http(s)://<curity_host>:<admin_port>/admin/api/restconf/data/base:profiles/base:profile=<token_profile_id>,oauth-service/base:settings/profile-oauth:authorization-server/profile-oauth:client-store/profile-oauth:config-backed/client=<client_id>"