CAS-OIDC-Anbindung
Bei dem Upgrade zu Confluence 8 wurde versucht CAS mit OIDC anzubinden. Da Confluence leider noch keine Unterstützung für den BackChannel-Logout hat, werden hier alle geleisteten Implementierungen festgehalten. Diese können bei einer möglichen Unterstützung verwendet werden.
Allgemeine Aufgabe für die OIDC-Anbindung
- Entfernen der CAS-Filter in
resource/opt/atlassian/confluence/confluence/WEB-INF/web.xml.tpl
- Verwendung des regulären
ConfluenceAuthenticator
inresource/opt/atlassian/confluence/confluence/WEB-INF/classes/seraph-config.xml-tpl
- Im initialen Setup muss OIDC konfiguriert werden (zum Beispiel nach der LDAP-Konfiguration):
# Create ldap configuration
postRequest "confluence/plugins/servlet/embedded-crowd/configure/ldap" "$(getLdapParameter)" "FALSE"
# Add permissions to admin group
postRequest "confluence/admin/permissions/doeditglobalpermissions.action" "$(getGlobalPermissionParameter)" "FALSE"
# Add cas oidc instead of using the apereo java cas client because the confluence integration is deprecated.
httpRequest "POST" "confluence/rest/authconfig/1.0/idps" "$(getCasOidcPayload)"
# Disable basic auth for the login form so that confluence redirects to cas on login.
disableBasicAuthLoginForm
function getCasOidcPayload() {
local payload fqdn clientID clientSecret
fqdn=$(doguctl config --global fqdn)
clientID=$(doguctl config -e "sa-cas/oidc_client_id")
clientSecret=$(doguctl config -e "sa-cas/oidc_client_secret")
payload+='{"name":"CAS-OIDC",'
payload+='"sso-type":"OIDC",'
payload+='"issuer-url":"https://'"${fqdn}"'/cas/oidc",'
payload+='"client-id":"'"${clientID}"'",'
payload+='"client-secret":"'"${clientSecret}"'",'
# shellcheck disable=SC2016
payload+='"username-claim":"${preferred_username}",'
payload+='"additional-scopes":[],'
payload+='"discovery-enabled":false,'
payload+='"enable-remember-me":true,'
payload+='"enabled":true,'
payload+='"button-text":"Login with CAS",'
payload+='"authorization-endpoint":"https://'"${fqdn}"'/cas/oidc/authorize",'
payload+='"token-endpoint":"https://'"${fqdn}"'/cas/oidc/accessToken",'
payload+='"userinfo-endpoint":"https://'"${fqdn}"'/cas/oidc/profile",'
payload+='"jit-configuration":{"user-provisioning-enabled":false}}'
echo "${payload}"
}
function disableBasicAuthLoginForm() {
echo "execute patch request to disable basic auth login form"
httpRequest "PATCH" "confluence/rest/authconfig/1.0/sso" '{"show-login-form":false}'
}
-
Bei einem nicht initialen Start muss OIDC aktualisiert werden (zum Beispiel nach der FQDN-Aktualisierung):
function subsequentStart() { echo "Confluence subsequent start detected." if [[ "${CREATE_CONFLUENCE_USERS_GROUP}" == "true" ]]; then echo "Updating users group..." update_users_group fi update_admin_group updateLdapSyncInterval updateFqdn updateOIDC doguctl state "starting" }
function updateOIDC() {
# activate OIDC
local fqdn clientID clientSecret oidcConfigID insertOrUpdateOIDC
fqdn="$( doguctl config --global fqdn )"
clientID="$( doguctl config -e "sa-cas/oidc_client_id" )"
clientSecret="$( doguctl config -e "sa-cas/oidc_client_secret" )"
oidcConfigID="$( execute_db_command_with_result "SELECT COALESCE((SELECT \"ID\" FROM \"AO_ED669C_IDP_CONFIG\" WHERE \"NAME\"='CAS-OIDC'), 1 /* default */)" )"
read -r -d ';' insertOrUpdateOIDC<<EOM
INSERT INTO "AO_ED669C_IDP_CONFIG" VALUES (
'[]' /* ADDITIONAL_JIT_SCOPES */,
'[]'/* ADDITIONAL_SCOPES */,
'https://${fqdn}/cas/oidc/authorize' /* AUTHORIZATION_ENDPOINT */,
'Login with CAS' /* BUTTON_TEXT */,
'${clientID}' /* CLIENT_ID */,
'${clientSecret}' /* CLIENT_SECRET */,
true /* ENABLED */,
true /* ENABLE_REMEMBER_ME */,
'${oidcConfigID}' /* ID */,
false /* INCLUDE_CUSTOMER_LOGINS */,
'https://${fqdn}/cas/oidc' /* ISSUER */,
NOW()::TIMESTAMP /* LAST_UPDATED */,
'' /* MAPPING_DISPLAYNAME */,
'' /* MAPPING_EMAIL */,
'' /* MAPPING_GROUPS */,
'CAS-OIDC' /* NAME */,
NULL /* SAML_IDP_TYPE */,
NULL /* SIGNING_CERT */,
'OIDC' /* SSO_TYPE */,
NULL /* SSO_URL */,
'https://${fqdn}/cas/oidc/accessToken' /* TOKEN_ENDPOINT */,
NULL /* USERNAME_ATTRIBUTE */,
'\${preferred_username}' /* USERNAME_CLAIM */,
'https://${fqdn}/cas/oidc/profile' /* USER_INFO_ENDPOINT */,
false /* USER_PROVISIONING_ENABLED */,
false /* USE_DISCOVERY */
) ON CONFLICT ("ID")
DO UPDATE SET
"ADDITIONAL_JIT_SCOPES" = '[]',
"ADDITIONAL_SCOPES" = '[]',
"AUTHORIZATION_ENDPOINT" = 'https://${fqdn}/cas/oidc/authorize',
"BUTTON_TEXT" = 'Login with CAS',
"CLIENT_ID" = '${clientID}',
"CLIENT_SECRET" = '${clientSecret}',
"ENABLED" = true,
"ENABLE_REMEMBER_ME" = true,
"INCLUDE_CUSTOMER_LOGINS" = false,
"ISSUER" = 'https://${fqdn}/cas/oidc',
"LAST_UPDATED" = NOW()::TIMESTAMP,
"MAPPING_DISPLAYNAME" = '',
"MAPPING_EMAIL" = '',
"MAPPING_GROUPS" = '',
"NAME" = 'CAS-OIDC',
"SAML_IDP_TYPE" = NULL,
"SIGNING_CERT" = NULL,
"SSO_TYPE" = 'OIDC',
"SSO_URL" = NULL,
"TOKEN_ENDPOINT" = 'https://${fqdn}/cas/oidc/accessToken',
"USERNAME_ATTRIBUTE" = NULL,
"USERNAME_CLAIM" = '\${preferred_username}',
"USER_INFO_ENDPOINT" = 'https://${fqdn}/cas/oidc/profile',
"USER_PROVISIONING_ENABLED" = false,
"USE_DISCOVERY" = false
;
EOM
execute_db_command "${insertOrUpdateOIDC}"
# deactivate confluence login form
local loginFormKey jsmLoginFormKey authFallbackKey
loginFormKey="com.atlassian.plugins.authentication.sso.config.show-login-form"
jsmLoginFormKey="com.atlassian.plugins.authentication.sso.config.show-login-form-for-jsm"
authFallbackKey="com.atlassian.plugins.authentication.sso.config.enable-authentication-fallback"
upsertBandanaValue '_GLOBAL' "${loginFormKey}" '<string>false</string>'
upsertBandanaValue '_GLOBAL' "${jsmLoginFormKey}" '<string>false</string>'
upsertBandanaValue '_GLOBAL' "${authFallbackKey}" '<string>false</string>'
}