Updated to WSO2 with start of config scrip

This commit is contained in:
Pascal Phelipot 2025-08-04 01:32:52 +02:00
parent 17696cd5dc
commit 918f755f7d
4 changed files with 211 additions and 11 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
data_*/* data_*/*
*_data/*

86
app_request_content.json Normal file
View File

@ -0,0 +1,86 @@
{
"name": "test_saml_app",
"inboundProtocolConfiguration": {
"saml": {
"manualConfiguration": {
"assertionConsumerUrls": [
"https://app-server-a:8080/"
],
"attributeProfile": {
"alwaysIncludeAttributesInResponse": false,
"enabled": true
},
"defaultAssertionConsumerUrl": "https://app-server-a:8080/",
"enableAssertionQueryProfile": false,
"idpEntityIdAlias": "",
"issuer": "saml-test-issuer",
"requestValidation": {
"enableSignatureValidation": true,
"signatureValidationCertAlias": "wso2carbon"
},
"responseSigning": {
"enabled": true,
"signingAlgorithm": "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"
},
"serviceProviderQualifier": "",
"singleLogoutProfile": {
"enabled": false,
"idpInitiatedSingleLogout": {
"enabled": false,
"returnToUrls": []
},
"logoutMethod": "BACKCHANNEL",
"logoutRequestUrl": "",
"logoutResponseUrl": ""
},
"singleSignOnProfile": {
"assertion": {
"audiences": [],
"digestAlgorithm": "http://www.w3.org/2001/04/xmlenc#sha256",
"encryption": {
"assertionEncryptionAlgorithm": "http://www.w3.org/2009/xmlenc11#aes256-gcm",
"enabled": true,
"keyEncryptionAlgorithm": "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"
},
"nameIdFormat": "urn/oasis/names/tc/SAML/1.1/nameid-format/emailAddress",
"recipients": []
},
"attributeConsumingServiceIndex": "",
"bindings": [
"HTTP_POST",
"HTTP_REDIRECT"
],
"enableIdpInitiatedSingleSignOn": false,
"enableSignatureValidationForArtifactBinding": false
}
}
}
},
"authenticationSequence": {
"type": "DEFAULT",
"steps": [
{
"id": 1,
"options": [
{
"idp": "LOCAL",
"authenticator": "basic"
}
]
}
],
"subjectStepId": 1,
"attributeStepId": 1
},
"advancedConfigurations": {
"discoverableByEndUsers": false
},
"description": "Regular web applications which use redirection inside browsers.",
"templateId": "776a73da-fd8e-490b-84ff-93009f8ede85",
"provisioningConfigurations": {
"inboundProvisioning": {
"provisioningUserstoreDomain": "RemoteLDAP2",
"proxyMode": false
}
}
}

View File

@ -17,19 +17,14 @@ services:
- action: rebuild - action: rebuild
path: ./conf/**/* path: ./conf/**/*
idp: idp:
image: quay.io/keycloak/keycloak:24.0.4 image: wso2/wso2is:5.11.0
restart: unless-stopped restart: unless-stopped
container_name: keycloak container_name: wso2
command: start-dev command: start-dev
ports: ports:
- '8080:8080' - '9443:9443'
environment:
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
#- KC_LOG_LEVEL=DEBUG
#- KC_HOSTNAME=localhost
volumes: volumes:
- ./data_keycloak:/opt/keycloak/data/ - ./data_wso2:/home/wso2/
grafana: grafana:
image: grafana/grafana-oss image: grafana/grafana-oss
restart: unless-stopped restart: unless-stopped
@ -38,4 +33,4 @@ services:
- '3000:3000' - '3000:3000'
volumes: volumes:
- ./conf/grafana.ini:/etc/grafana/grafana.ini:ro - ./conf/grafana.ini:/etc/grafana/grafana.ini:ro
- ./data_grafana:/var/lib/grafana - ./data_grafana:/var/lib/grafana

118
wso2_api.py Normal file
View File

@ -0,0 +1,118 @@
import httpx
import asyncio
import base64
from dataclasses import dataclass, asdict
import logging
import pprint
import difflib
logging.basicConfig(level=logging.DEBUG)
logging.getLogger("httpcore").setLevel(logging.WARNING)
logging.getLogger("httpx").setLevel(logging.WARNING)
@dataclass
class UniqueIDReadOnlyLDAPUserStoreManagerProperties():
ConnectionURL: str = "ldap://"
ConnectionName: str = "uid=,ou="
ConnectionPassword: str = "password"
UserSearchBase: str = "ou=Users,dc=wso2,dc=org"
UserNameAttribute: str = "uid"
UserNameSearchFilter: str = "(&(objectClass=person)(uid=?))"
UserNameListFilter: str = "(objectClass=person)"
UserIDAttribute: str = "uid"
UserIdSearchFilter: str = "(&(objectClass=person)(uid=?))"
BackLinksEnabled: bool = True
MemberOfAttribute: str = "memberOf"
# Optionnal mon cul
Disabled: bool = False
ReadGroups: bool = True
GroupSearchBase: str = "ou=Groups,dc=wso2,dc=org"
GroupNameAttribute: str = "cn"
GroupNameSearchFilter: str = "(&(objectClass=groupOfNames)(cn=?))"
GroupNameListFilter: str = "(objectClass=groupOfNames)"
CaseInsensitiveUsername: bool = True
MembershipAttribute: str = "member"
# Undocumented ???
UserEntryObjectClass: str = "inetOrgPerson"
def compare_dicts(d1, d2):
diff = ('\n' + '\n'.join(difflib.ndiff(
pprint.pformat(d1).splitlines(),
pprint.pformat(d2).splitlines()))
)
logging.info("diff: %s", diff)
async def create_keystore(client: httpx.AsyncClient):
url = "https://localhost:9443/t/carbon.super/api/server/v1/userstores/"
data = {
"typeId": base64.urlsafe_b64encode(b"UniqueIDReadOnlyLDAPUserStoreManager").decode("utf-8").rstrip("="),
"description": "New user store from API",
"name": "RemoteLDAP2",
"properties": [
{
"name": key,
"value": value
}
for key, value in asdict(UniqueIDReadOnlyLDAPUserStoreManagerProperties()).items()
]
}
# FIXME: this works to create the userstore but the Java is not very happy from it
resp = await client.post(url, json=data)
logging.debug("request: %s", resp.request.content)
logging.debug("resp [%s]: %s", resp.status_code, resp.json())
async def create_idp(client: httpx.AsyncClient):
url = "https://localhost:9443/t/carbon.super/api/server/v1/identity-providers"
data = {
"name": "test_idp",
"description": "A test IDP",
"provisioning": {
"jit": {
"isEnabled": True,
"scheme": "PROVISION_SILENTLY",
"userstore": "RemoteLDAP2" # Name of the userstore
},
"outboundConnectors": None
}
}
resp = await client.post(url, json=data)
logging.debug("request: %s", resp.request.content)
logging.debug("resp [%s]: %s", resp.status_code, resp.json())
async def create_sp(client: httpx.AsyncClient, sp_name: str):
url = "https://localhost:9443/t/carbon.super/api/server/v1/applications"
data = {
"name": sp_name,
"description": f"A SP for {sp_name}",
"accessUrl": "https://example.com/login",
"inboundProtocolConfiguration": {
"saml": {
}
},
"outboundProvisioningIdps": [
{
"idp": "test_idp"
}
]
}
resp = await client.post(url, json=data)
logging.debug("request: %s", resp.request.content)
logging.debug("resp [%s]: %s", resp.status_code, resp.json())
async def main():
auth = httpx.BasicAuth(username="admin", password="admin")
async with httpx.AsyncClient(auth=auth, verify=False) as client:
try:
# await create_keystore(client)
# await create_idp(client)
await create_sp(client, "portal")
except Exception as err:
logging.exception("Failure during request to WSO2")
if __name__ == "__main__":
asyncio.run(main())