diff --git a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/etc/nevis/k8s-nevisauth-7022472ae407577ae604bbb8.yaml b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/etc/nevis/k8s-nevisauth-7022472ae407577ae604bbb8.yaml
index 649394d..5e66bb1 100644
--- a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/etc/nevis/k8s-nevisauth-7022472ae407577ae604bbb8.yaml
+++ b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/etc/nevis/k8s-nevisauth-7022472ae407577ae604bbb8.yaml
@@ -46,7 +46,7 @@ spec:
podDisruptionBudget:
maxUnavailable: "50%"
git:
- tag: "r-9849dba282e5e9421988bf7092f242ff73d83ce5"
+ tag: "r-04ad6fd7455702c2a591f4a7b8d6c94222de911e"
dir: "DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth"
credentials: "git-credentials"
database:
diff --git a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/keypass b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/keypass
new file mode 100755
index 0000000..5b0d317
--- /dev/null
+++ b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/keypass
@@ -0,0 +1,2 @@
+#!/bin/bash
+echo 'password'
\ No newline at end of file
diff --git a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/truststore.jks b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/truststore.jks
new file mode 100644
index 0000000..77cb5d8
Binary files /dev/null and b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/truststore.jks differ
diff --git a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/truststore.p12 b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/truststore.p12
new file mode 100644
index 0000000..be0bb02
Binary files /dev/null and b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/truststore.p12 differ
diff --git a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/truststore.pem b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/truststore.pem
new file mode 100644
index 0000000..d398c57
--- /dev/null
+++ b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/keys/trust/idp-pem-atb-enc/truststore.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFdzCCA1+gAwIBAgIUdL2pr5w+jKA9HF9llVbMRTK4MO8wDQYJKoZIhvcNAQEL
+BQAwSzELMAkGA1UEBhMCQ0gxDTALBgNVBAcMBEJlcm4xEjAQBgNVBAoMCUFHT1Yg
+V29yazEZMBcGA1UEAwwQYXRiLXdvcmstaWRwLWtleTAeFw0yNTA5MDMwNjQ2Mjha
+Fw0zNTA5MDEwNjQ2MjhaMEsxCzAJBgNVBAYTAkNIMQ0wCwYDVQQHDARCZXJuMRIw
+EAYDVQQKDAlBR09WIFdvcmsxGTAXBgNVBAMMEGF0Yi13b3JrLWlkcC1rZXkwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2s6fPlpWv/1zEnail7TCUphEQ
+A/dr/uY+qQqA/okB+Okd5hGDow7zBe/zICn7PJlGXzkq87o4Q3ZFvOFLqvlhwprp
+OQquIviN6VBss2F3c174Zkk7ksciLQzPYjGBgw+l/ZeZY/AOYBeConsrHobTbjPd
+StI8FZr8zVnamMWd/nBnryA5mZy9+vKz3iPJXPXZmyhBnOJfPZjMmkLvY9wEfGfc
+rGrbqh6f7grleVNU16Rt46TtJRIqWEAdqi1I81d3kEWuqHkYCZf1ZJpDtprJPVko
+fWViFzMz7zuAK5kdaGVwu0R7zeKz6FCHWWQ5bqScQbZ53zX6D3sP6ZNnZXdo6n0L
+i+x17sgZa6VJtWF6s/UUxl8jPteprfRHrgIT3yKK9ewpXEhcc4aNJyCTiXpicOOn
+QUBkkxyT7MtG1j51GPFcoFsBn4X9A1BXUmz2+YrDfFKtj0LwKZe6naI5v+FGtqeQ
+/GeRpaFISwg/L5ewHe3NTH//8ZyWQsbJ2FEIff3LM+0+ivrORJs45GW12ny6MDY1
+Q8PTEsPL/9nhY1Mf99qpB9ivouVF/vGDWont16PhaZ2N31Osbbok3Emfbk0MVfvh
+MuY0PPX/eWfn+5WlxBegS9PXbrcNW7MV0vsow8Js9+B29nao/VeFOQDfrU9p//xu
+nDkeh9z5vqRP7clgMQIDAQABo1MwUTAdBgNVHQ4EFgQUqqmWA9MTwbzRFOfxZbu8
+nIyk4dEwHwYDVR0jBBgwFoAUqqmWA9MTwbzRFOfxZbu8nIyk4dEwDwYDVR0TAQH/
+BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAnh1nayZy7CjTDvXjht0jNEyCPahL
+/gzcfx173FWnDbG3DMqjKB0u7bbpWIdStvTHpvs4NOg7H1/3Xc3cu3vtw6PF3Tkt
+ZGJrMgZ5H9BUPW7BeNPqylh0Xj9vWUhxOdRfthzHcuSg2H6k5GBe+ROVIWLcc5g2
+vIuEEnpL9H5mlt4MofodPJjDrOvbJ5eDOGnNlcSKgPy8ZxrvyesmjFquu9/941p5
+wOpGhfVRH6U9GBIy1wWjjO4y2oRtgdgV0Dm57VNaxNi4R0cRW+eg7H7jED2gWVdS
+Zftkrq44/lXFnWZDXWq8JJs0QPPD30i8fbGvZjRbrVQus5wW+dlirSkljQD8WpiY
+N7PS2y+Io9WDetabxDSkHQGduldlHqnjvvR7TtLBT73fbmrra7nLrxbwAyQs/lp9
+r2904tzgBfhHb5GCrYE1s3h339eb/HXZlPqG1EcYimsAIyyBQ7WyHOgXq5RqwgbW
+9O8aQUWPQrdtWrv8BkYSjjgDSxj9Pu7yBFnSdyI879uvBZDYovm/MmgcguAaJ8UC
+PUcchbvgdLJHnbBA5aFm/Fkhb2WKi3Q0vExUHM3sXazJAAjIplbunHkqf8Wc7lva
+94y3AXN9dg5LEjcwkjQbyGmmuSFq0Hse0b1KE+4INYUigECUcXuKYWrP0RuPzCKU
+4g4p3ZpFGmoq4lM=
+-----END CERTIFICATE-----
diff --git a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/esauth4.xml b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/esauth4.xml
index 423b6e5..7e482b0 100644
--- a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/esauth4.xml
+++ b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/esauth4.xml
@@ -134,6 +134,15 @@
+
+
+
+
+
+
+
+
+
@@ -159,10 +168,13 @@
+
+
+
@@ -1398,7 +1410,7 @@
-
+
@@ -1546,12 +1558,21 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1690,6 +1711,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2231,15 +2268,6 @@
-
-
-
-
-
-
-
-
-
@@ -3452,6 +3480,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/saml_idp_agov_sec_authorization.groovy b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/saml_idp_agov_sec_authorization.groovy
new file mode 100644
index 0000000..d89725f
--- /dev/null
+++ b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/saml_idp_agov_sec_authorization.groovy
@@ -0,0 +1,179 @@
+boolean isEnabled() {
+ def paths = parameters.get("paths")
+ if (paths && !paths.isEmpty()) {
+ for (path in paths.split(',')) {
+ String url = request.currentResource
+ if (url.matches(path)) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+boolean isLevel(String role) {
+ if (role != null && role.isNumber()) {
+ def number = Integer.parseInt(role)
+ if (number > 0 && number <= 9) {
+ return true
+ }
+ }
+ return false
+}
+
+int getCurrentLevel() {
+ int level = 1 // level 1 is reached by definition on successful authentication
+ // levels are stored as roles once the authentication is done
+ for (String role : response.getActualRoles()) {
+ if (isLevel(role)) {
+ Integer number = Integer.parseInt(role)
+ if (number > level) {
+ level = number
+ }
+ }
+ }
+ LOG.debug("current level: $level")
+ return level
+}
+
+Integer getRequestedLevel() {
+ // try to determine required level based on SAML request (SP-initiated)
+ def context = session['ch.nevis.auth.saml.request.authnContextClassRef']
+ if (context == null) {
+ // this is expected for non-Nevis SAML partners
+ LOG.debug("unable to determine required authentication level: no AuthnContext")
+ return null
+ }
+ String prefix = 'urn:nevis:level:'
+ Integer level = null
+ if (context.contains(prefix)) {
+ def start = context.indexOf(prefix) // the prefix can appear anywhere in the context but only once
+ def remainder = context.substring(start + prefix.length())
+ for (String candidate : remainder.split(',')) {
+ if (!candidate.isNumber()) {
+ continue // must be an actual role
+ }
+ def number = Integer.parseInt(candidate)
+ if (level == null || number < level) {
+ level = number
+ }
+ }
+ }
+ if (level == null) {
+ // an AuthnContext has been sent but it does not contain the required authentication level
+ LOG.debug("unable to determine required authentication level from request: $context")
+ }
+ else {
+ LOG.info("extracted required authentication level from request: $context -> $level")
+ }
+ return level
+}
+
+Integer getRequiredLevel(levels, String issuer) {
+ // try to determine required level based on request
+ def level = getRequestedLevel()
+ if (level != null) {
+ LOG.info("required authentication level from request: $level")
+ return level
+ }
+ // else determine required level based on configuration (IDP-initiated or no authnContextClassRef sent)
+ if (issuer != null && levels.containsKey(issuer)) {
+ level = levels[issuer]
+ LOG.debug("required authentication level for issuer $issuer defined as $level")
+ return level
+ }
+ // else return null
+ LOG.debug("required authentication level for issuer $issuer is not defined")
+ return null
+}
+
+void setAuthnContext() {
+ def parts = [] as Set
+ def authLevel = response.getAuthLevel()
+ if (authLevel != null) {
+ if (isLevel(authLevel)) {
+ parts.add("urn:nevis:level:$authLevel")
+ }
+ else { // might be legacy auth.weak / auth.strong
+ parts.add(authLevel)
+ }
+ }
+ for (String role : response.getActualRoles()) {
+ if (isLevel(role)) { // previous authLevels might have been added to the roles already
+ parts.add("urn:nevis:level:$role")
+ }
+ // levels can also be normal roles so we add them always
+ parts.add(role)
+ }
+ def value = parts.sort().join(",")
+ LOG.debug("calculated AuthnContextClassRef for SAML Response: $value")
+ session['saml.idp.response.authncontext'] = value
+}
+
+boolean stepupRequired(levels, String issuer) {
+
+ Integer requiredLevel = getRequiredLevel(levels, issuer)
+ if (requiredLevel == null) {
+ LOG.info("unable to determine required authentication level for request from issuer $issuer")
+ setAuthnContext()
+ return false
+ }
+
+ Integer currentLevel = getCurrentLevel()
+ if (currentLevel >= requiredLevel) {
+ LOG.info("required authentication level $requiredLevel has been reached (current level $currentLevel)")
+ setAuthnContext()
+ return false
+ }
+
+ LOG.info("required authentication level $requiredLevel has not been reached (current level $currentLevel) - session upgrade needed")
+ request.setRequiredRoles("$requiredLevel")
+ return true
+}
+
+boolean hasAnyRequiredRole(i2r, issuer) {
+ if (issuer != null && i2r.containsKey(issuer)) {
+ def roles = i2r[issuer]
+ for (role in response.getActualRoles()) {
+ if (roles.contains(role)) {
+ return true
+ }
+ }
+ }
+}
+
+if (!isEnabled()) {
+ LOG.info("skipping SAML authorization checks.")
+ response.setResult('ok') // skip execution
+ return
+}
+
+// issuer set by IdentityProviderState (SP-initiated)
+def issuer = session['ch.nevis.auth.saml.request.issuer']
+
+// issuer to minimum required authentication level
+def i2l = [:]
+
+
+if (stepupRequired(i2l, issuer)) {
+ LOG.info("authentication level stepup required.")
+ response.setResult("stepup")
+ return // we are done for now
+}
+
+// issuer to list of required roles
+def i2r = [:]
+
+
+// issuer to ResultCond name
+def i2e = [:]
+i2e.put('https://trustbroker.agov-d.azure.adnovum.net', 'forbidden_0')
+
+
+if (!i2r.isEmpty() && !hasAnyRequiredRole(i2r, issuer)) {
+ LOG.info("required roles check failed.")
+ response.setResult(i2e[issuer])
+ return // we are done
+}
+
+response.setResult('ok')
diff --git a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/saml_idp_agov_sec_dispatcher.groovy b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/saml_idp_agov_sec_dispatcher.groovy
new file mode 100644
index 0000000..1aebdbb
--- /dev/null
+++ b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/saml_idp_agov_sec_dispatcher.groovy
@@ -0,0 +1,174 @@
+import java.util.zip.Inflater
+import java.util.zip.InflaterInputStream
+
+import groovy.xml.XmlSlurper
+import groovy.xml.slurpersupport.GPathResult
+
+/**
+ * Gets the value of the Referer header.
+ * If the header is missing the fallback is returned.
+ *
+ * Do NOT remove this method.
+ * This method is used when SAML IDP / Dispatch Error Redirect is not set.
+ * A call to this method will be generated into this script (~line 157).
+ *
+ * @param fallback - value to return if the Referer header is missing
+ * @return value of header or fallback
+ */
+def getReferer(String fallback) {
+ return request.getHttpHeader('Referer') ?: fallback
+}
+
+def redirect(String url) {
+ outargs.put('nevis.transfer.type', 'redirect')
+ outargs.put('nevis.transfer.destination', url)
+}
+
+/**
+ * Extracts the content of the Issuer element from a parsed SAML message.
+ * The Issuer is optional according to SAML specification but we need it for dispatching.
+ *
+ * @param xml - as parsed by Groovy XmlSlurper
+ * @return text content of Issuer element converted or null
+ */
+static String getIssuer(GPathResult xml) {
+ return xml.depthFirst().find { GPathResult node -> {
+ node.name().endsWith(":Issuer") || node.name().equalsIgnoreCase("Issuer")
+ }
+ }?.text()
+}
+
+String getIssuer(String value) {
+ if (value == null) {
+ return
+ }
+ String text
+ byte[] decoded
+ def parser = new XmlSlurper()
+ // if value is raw xml then continue otherwise try to parse the base64 encoding
+ if (value.startsWith("<")) {
+ text = new String(value)
+ }
+ else {
+ decoded = value.decodeBase64()
+ text = new String(decoded)
+ LOG.info("received SAML request $value")
+ }
+
+ // after decoded, if redirect binding, we need to parse string to xml
+ if (text.startsWith("<")) {
+ LOG.debug("assuming POST/SOAP binding")
+ // plain String (POST/SOAP parameter)
+ def xml = parser.parseText(text)
+ return getIssuer(xml)
+ }
+ else {
+ LOG.debug("assuming redirect binding")
+ // should be deflate encoded (query parameter)
+ def is = new InflaterInputStream(new ByteArrayInputStream(decoded), new Inflater(true))
+ def xml = parser.parse(is)
+ return getIssuer(xml)
+ }
+}
+
+def dispatchIssuer(i2s, String issuer) {
+ def result = i2s.get(issuer)
+ if (result == null) {
+ throw new RuntimeException("No SP found for issuer '$issuer'. Hint: check SAML SP Connector patterns.")
+ }
+ response.setResult(result)
+ session.put("saml.inbound.issuer", issuer)
+ session.put('saml.idp.result', result) // remember decision for sub-sequent requests without a SAML message
+}
+
+def dispatchMessage(i2s, String message) {
+ def issuer = getIssuer(message)
+ if (issuer == null) {
+ throw new RuntimeException("No issuer found in incoming SAML message. Giving up.")
+ }
+ session.put("saml.inbound.issuer", issuer)
+ dispatchIssuer(i2s, issuer)
+}
+
+if (parameters.get('logoutConfirmation') == 'true' && "stepup" == request.getMethod()) {
+ String url = request.currentResource
+ def path = new URL(url).getPath()
+ if (path.endsWith("/logout")) {
+ // next AuthState will show a logout confirmation GUI
+ response.setResult('confirm')
+ return
+ }
+}
+
+// ensure session exists
+if (request.getSession(false) == null) {
+ session = request.getSession(true).getData()
+}
+
+// issuer (any case) -> ResultCond name
+def i2s = new TreeMap(String.CASE_INSENSITIVE_ORDER)
+
+
+i2s.put('https://trustbroker.agov-d.azure.adnovum.net', 'state0')
+
+def spInitiatedAllowed = parameters.get('spInitiated') == 'true'
+def idpInitiatedAllowed = parameters.get('idpInitiated') == 'true'
+
+try {
+ if (spInitiatedAllowed && inargs.containsKey('SAMLRequest')) { // SP-initiated authentication
+ LOG.debug("found SAMLRequest parameter for SP-initiated authentication")
+ String message = inargs.get('SAMLRequest')
+ dispatchMessage(i2s, message)
+ return
+ }
+
+ if (inargs.containsKey('SAMLResponse')) { // response to IDP-initiated SAML Logout
+ LOG.debug("found SAMLResponse parameter")
+ String message = inargs.get('SAMLResponse')
+ dispatchMessage(i2s, message)
+ return
+ }
+
+ if (spInitiatedAllowed && inargs.containsKey('soapheader')) { // SP-initiated SOAP with soapheader
+ LOG.debug("found soapheader parameter for SP-initiated")
+ String message = inargs.get('soapheader')
+ dispatchMessage(i2s, message)
+ return
+ }
+
+ if (spInitiatedAllowed && inargs.containsKey('')) { // SP-initiated SOAP with empty
+ LOG.debug("found empty parameter for SP-initiated SOAP message")
+ String message = inargs.get('')
+ dispatchMessage(i2s, message)
+ return
+ }
+
+ String issuer = inargs['Issuer'] ?: inargs['issuer']
+ if (idpInitiatedAllowed && issuer != null) { // IDP-initiated authentication
+ LOG.debug("found Issuer parameter for IDP-initiated authentication")
+ dispatchIssuer(i2s, issuer)
+ return
+ }
+
+ // used as fallback in case of ?logout (we need an IdentityProviderState)
+ if (inargs.containsKey("logout") && session.containsKey('saml.idp.result')) {
+ def result = session.get('saml.idp.result')
+ LOG.debug("dispatching to last used ResultCond: $result")
+ response.setResult(result)
+ return
+ }
+}
+catch (RuntimeException e) {
+ LOG.error("Error while dispatching SAML message: ${e.message}")
+}
+
+def redirectEnabled = parameters.get('errorHandling') == 'redirect'
+if (redirectEnabled) {
+ def location = getReferer('/')
+ LOG.info("Unable to dispatch request. Giving up and redirecting (back) to $location")
+ redirect(location)
+}
+else {
+ LOG.info("Unable to dispatch request. Giving up and showing error GUI.")
+ response.setResult('default')
+}
diff --git a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/saml_idp_logout_confirm.groovy b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/saml_idp_logout_confirm.groovy
new file mode 100644
index 0000000..8f7202b
--- /dev/null
+++ b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/auth/var/opt/nevisauth/default/conf/saml_idp_logout_confirm.groovy
@@ -0,0 +1,64 @@
+def redirect(location) {
+ outargs.put('nevis.transfer.type', 'redirect')
+ outargs.put('nevis.transfer.destination', location)
+}
+
+def getReturnURL() {
+ if (inargs.containsKey('return')) {
+ return inargs.get('return')
+ }
+ // determine returnURL based on Referer header (if present and not pointing to this page)
+ def referer = request.getHttpHeader('Referer')
+ if (referer == null) {
+ LOG.debug('no Referer header found')
+ return null
+ }
+ // strip query String for comparison
+ String previous = referer.contains('?') ? referer.substring(0, referer.indexOf("?")) : referer
+ def current = request.getCurrentResource()
+ if (current.startsWith(previous)) {
+ LOG.debug("Referer header $referer cannot be used as return URL - cyclic redirect")
+ return null
+ }
+ return referer
+}
+
+if (inargs.containsKey('logout-confirm')) {
+ def current = request.getCurrentResource()
+ // user has confirmed logout -> replace /logout with /?logout
+ String location
+ if (current.contains('?')) {
+ location = current.replace("/logout?", "/?logout&")
+ }
+ else {
+ location = current.replace("/logout", "/?logout")
+ }
+ redirect(location)
+ return
+}
+
+if (inargs.containsKey('logout-abort')) {
+ // user has aborted logout -> redirect to stored return URL
+ def location = session.get('logout-abort-url')
+ redirect(location)
+ return
+}
+
+// user has not clicked any button -> render GUI
+response.setGuiName('saml_logout_confirm')
+response.setGuiLabel('title.logout.confirmation')
+// not setting a target as the API has been removed
+response.addInfoGuiField('info', 'info.logout.confirmation', null)
+response.addButtonGuiField('logout-confirm', 'continue.button.label', 'true')
+
+def returnURL = getReturnURL()
+
+if (returnURL != null) {
+ // store return URL in session
+ session.put('logout-abort-url', returnURL)
+}
+
+if (session.containsKey('logout-abort-url')) {
+ // add cancel button to go back
+ response.addButtonGuiField('logout-abort', 'cancel.button.label', 'true')
+}
\ No newline at end of file
diff --git a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/proxy-idp/etc/nevis/k8s-nevisproxy-idp-0ceb05c56644a59d648c13b9.yaml b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/proxy-idp/etc/nevis/k8s-nevisproxy-idp-0ceb05c56644a59d648c13b9.yaml
index f58ff0c..a896221 100644
--- a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/proxy-idp/etc/nevis/k8s-nevisproxy-idp-0ceb05c56644a59d648c13b9.yaml
+++ b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/proxy-idp/etc/nevis/k8s-nevisproxy-idp-0ceb05c56644a59d648c13b9.yaml
@@ -47,7 +47,7 @@ spec:
podDisruptionBudget:
maxUnavailable: "50%"
git:
- tag: "r-ca58de85fdf7a911b85ea6cd56b4c1a3d7f94fd6"
+ tag: "r-04ad6fd7455702c2a591f4a7b8d6c94222de911e"
dir: "DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/proxy-idp"
credentials: "git-credentials"
database:
diff --git a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/proxy-idp/var/opt/nevisproxy/default/host-auth.agov-w.azure.adnovum.net/WEB-INF/web.xml b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/proxy-idp/var/opt/nevisproxy/default/host-auth.agov-w.azure.adnovum.net/WEB-INF/web.xml
index d0dae25..7df3f11 100644
--- a/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/proxy-idp/var/opt/nevisproxy/default/host-auth.agov-w.azure.adnovum.net/WEB-INF/web.xml
+++ b/DEFAULT-ADN-AGOV-PROJECT/DEFAULT-ADN-AGOV-INV/proxy-idp/var/opt/nevisproxy/default/host-auth.agov-w.azure.adnovum.net/WEB-INF/web.xml
@@ -1112,6 +1112,11 @@
/pwreset/*
+
+ SessionHandler_Auth_Realm_Main_IDP
+ /SAML2/SECSSO/*
+
+
SessionHandler_Auth_Realm_Main_IDP
/SAML2/SSO/*
@@ -1203,6 +1208,11 @@
/pwreset/*
+
+ AuthenticationService_Auth_Realm_Main_IDP
+ /SAML2/SECSSO/*
+
+
AuthenticationService_Auth_Realm_Main_IDP
/SAML2/SSO/*
@@ -1635,10 +1645,10 @@
true
-
+
Hosting_Default
-
+
ch::nevis::isiweb4::servlet::defaults::DefaultServlet
@@ -1754,6 +1764,11 @@
Hosting_Default
/AUTH/RECOVERY/*
+
+
+ Hosting_Default
+ /SAML2/SECSSO/*
+
Hosting_Default