1 file added, 19 files updated and 2 files deleted

This commit is contained in:
haburger 2024-10-21 07:33:30 +00:00
parent 2705180320
commit 196c3ba3a0
28 changed files with 261 additions and 396 deletions

View File

@ -1,12 +1,12 @@
schemaVersion: "1.0"
bundles:
- "nevisadmin-plugin-oauth:8.2405.2.0"
- "nevisadmin-plugin-authcloud:8.2405.2.0"
- "nevisadmin-plugin-nevisidm:8.2405.2.0"
- "nevisadmin-plugin-mobile-auth:8.2405.2.0"
- "nevisadmin-plugin-fido2:8.2405.2.0"
- "nevisadmin-plugin-nevisdp:8.2405.2.0"
- "nevisadmin-plugin-nevisauth:8.2405.2.0"
- "nevisadmin-plugin-nevisproxy:8.2405.2.0"
- "nevisadmin-plugin-nevisdetect:8.2405.2.0"
- "nevisadmin-plugin-base-generation:8.2405.2.0"
- "nevisadmin-plugin-oauth:8.2405.2.0"
- "nevisadmin-plugin-nevisdetect:8.2405.2.0"
- "nevisadmin-plugin-nevisauth:8.2405.2.0"
- "nevisadmin-plugin-nevisdp:8.2405.2.0"
- "nevisadmin-plugin-nevisproxy:8.2405.2.0"
- "nevisadmin-plugin-mobile-auth:8.2405.2.0"
- "nevisadmin-plugin-nevisidm:8.2405.2.0"
- "nevisadmin-plugin-fido2:8.2405.2.0"
- "nevisadmin-plugin-authcloud:8.2405.2.0"

View File

@ -5,14 +5,6 @@
</AuthState>
<AuthState name="${state.entry}_dispatch" class="ch.nevis.esauth.auth.states.standard.ConditionalDispatcherState" final="false" resumeState="true">
<ResultCond name="default" next="${state.exit.5}"/>
<!-- TODO/haburger/2024-AUG-20: remove Google after successfull migration to Friendly Captcha -->
<!-- <ResultCond name="cancel, hasCaptchaInfos, visible" next="${state.exit.2}"/> -->
<!-- <ResultCond name="hasCode, hasCaptchaInfos, visible" next="${state.exit.2}"/> -->
<!-- <ResultCond name="hasCaptchaInfos, invalidUrlTicket, visible" next="${state.entry}_enterEmail"/> -->
<!-- <ResultCond name="hasCaptchaInfos, continue, visible" next="${state.entry}_enterEmail"/> -->
<!-- <ResultCond name="invalidUrl, hasCaptchaInfos, visible" next="${state.entry}_ticketInvalid"/> -->
<ResultCond name="invalidUrlTicket" next="${state.exit.5}"/>
<ResultCond name="hasCode" next="${state.exit.2}"/>
<ResultCond name="cancel" next="${state.exit.2}"/>
@ -36,11 +28,6 @@
<property name="condition:invalidUrl" value="#{!inctx.getProperty('connection.actualURL').matches('((https://.*/AUTH/RECOVERY/\\?$)|(https://.*/AUTH/RECOVERY/$)|(https://.*/AUTH/RECOVERY/\\?language=(de|fr|it|en))|(https://.*/AUTH/RECOVERY/\\?cd=.*))')}"/>
<property name="condition:invalidUrlTicket" value="${notes:invalidUrlTicket}"/>
<property name="condition:hasCaptchaInfos" value="#{sess.get('agov.recovery.captchaSettings.puzzleUrl')}"/>
<!-- TODO/haburger/2024-AUG-20: remove Google after successfull migration to Friendly Captcha -->
<!-- <property name="condition:hasCaptchaInfos" value="#{sess.get('agov.recovery.json.accountUrl')}"/> -->
<!-- <property name="condition:continue" value="#{inargs.containsKey('continue')}"/> -->
<!-- <property name="condition:visible" value="#{sess.get('agov.recovery.X-ReCAPTCHA-Integration') eq 'VISIBLE'}"/> -->
</AuthState>
<AuthState name="${state.entry}_loginFactorQuestion" class="ch.nevis.esauth.auth.states.standard.ConditionalDispatcherState" final="true" resumeState="true">
<ResultCond name="cancel" next="${state.exit.2}"/>
@ -113,13 +100,6 @@
<GuiElem name="captchaSettings.enabled" type="hidden" value="${sess:agov.recovery.captchaSettings.enabled}" optional="true"/>
<GuiElem name="friendlyCaptchaSettings.siteKey" type="hidden" value="${sess:agov.recovery.captchaSettings.siteKey}" optional="true"/>
<GuiElem name="friendlyCaptchaSettings.puzzleUrl" type="hidden" value="${sess:agov.recovery.captchaSettings.puzzleUrl}" optional="true"/>
<!-- TODO/haburger/2024-AUG-20: remove Google after successfull migration to Friendly Captcha -->
<!-- <GuiElem name="captchaSettings.reCaptchaInvisibleSiteKey" type="hidden" value="${sess:agov.recovery.json.captchaSettings.reCaptchaInvisibleSiteKey}" optional="true"/> -->
<!-- <GuiElem name="captchaSettings.reCaptchaVisibleSiteKey" type="hidden" value="${sess:agov.recovery.json.captchaSettings.reCaptchaVisibleSiteKey}" optional="true"/> -->
<!-- <GuiElem name="X-ReCAPTCHA-Integration" type="hidden" value="${sess:agov.recovery.X-ReCAPTCHA-Integration}" optional="true"/> -->
<GuiElem name="cancel" type="submit" label="cancel.button.label" value="cancel"/>
<GuiElem name="submit" type="submit" label="submit.button.label" value="submit"/>
</Gui>

View File

@ -1,8 +1,6 @@
import groovy.xml.XmlSlurper
import groovy.json.JsonSlurper
//import ch.nevis.esauth.util.httpclient.api.HttpClients
//import ch.nevis.esauth.util.httpclient.api.Http
import io.opentelemetry.api.trace.Span
int getRequestedLevel(String authnContextClassRef, def roleList){
if (!authnContextClassRef) {
@ -58,11 +56,13 @@ if (requestedRoleLevelNumber == 0 || session.get('ch.nevis.auth.saml.request.sco
}
try {
def spanCtxt = Span.current().getSpanContext()
def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}"
def jsonSlurper = new JsonSlurper()
def url = parameters.get('url') + '?entity-id=' + session.get('ch.nevis.auth.saml.request.scoping.requesterId')
LOG.debug('Request url: ' + url)
def httpClient = HttpClients.create(parameters)
def httpResponse = Http.get().url(url).build().send(httpClient)
def httpResponse = Http.get().url(url).header('traceparent', traceparent).build().send(httpClient)
LOG.debug('Response Message: ' + httpResponse.reasonPhrase())
LOG.debug('Response Status Code: ' + httpResponse.code())
LOG.debug('Response: ' + httpResponse.bodyAsString())

View File

@ -1,101 +1,63 @@
def url = parameters.get('url')
def email = inargs['userInputValue_prompt.email']
def token = inargs['captcha_response']?: 'MISSING'
def ip = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown'
def userAgent = request.getLoginContext()['connection.HttpHeader.user-agent'] ?: request.getLoginContext()['connection.HttpHeader.User-Agent'] ?: 'unknown'
def payload = "{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }"
LOG.debug('Token: ' + token)
LOG.debug('Payload: ' + payload)
try {
def httpClient = HttpClients.create(parameters)
def httpResponse = Http.post()
.url(url)
.header("Accept", "application/json")
.header("X-FriendlyCAPTCHA-Token", token)
.entity(Http.entity()
.content(payload)
.contentType("application/json")
.build())
.build()
.send(httpClient)
LOG.debug('Response Message: ' + httpResponse.reasonPhrase())
LOG.debug('Response Status Code: ' + httpResponse.code())
LOG.debug('Response: ' + httpResponse.bodyAsString())
if (httpResponse.code() == 200) {
if (httpResponse.bodyAsString().contains('SUCCESSFUL')) {
response.setResult('ok')
return
} else {
LOG.warn("Friendly captcha not successful for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }'")
response.setResult('exit.1')
return
}
} else {
LOG.error("Friendly captcha failed with statuscode ${httpResponse.code()} for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }'")
response.setResult('error')
response.setError(1, 'Unexpected HTTP reponse')
}
} catch (all) {
// Handle exception and set the transition
LOG.error("Friendly captcha failed with a general error '${all}' for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }', service-url: ${url}")
response.setResult('error')
response.setError(1, 'Exception during HTTP call')
}
// TODO/haburger/2024-AUG-20: remove if reCaptcha is not needed anymore
//
// def payload = '{ "email": "' + inargs['userInputValue_prompt.email'] + '", "action": "LOGIN", "userIp": "' + ip + '", "userAgent": "' + userAgent + '"}'
//
// LOG.info('Token: ' + inargs['recaptcha_response'])
// LOG.info('Integration: ' + session['agov.fido2.X-ReCAPTCHA-Integration'])
// LOG.info('Payload: ' + payload)
//
// try {
//
// def httpClient = HttpClients.create(parameters)
// def httpResponse = Http.post()
// .url(url)
// .header("Accept", "application/json")
// .header("X-ReCAPTCHA-Token", inargs['recaptcha_response'])
// .header("X-ReCAPTCHA-Integration", session['agov.fido2.X-ReCAPTCHA-Integration'])
// .entity(Http.entity()
// .content(payload)
// .contentType("application/json")
// .build())
// .build()
// .send(httpClient)
//
// LOG.info('Response Message: ' + httpResponse.reasonPhrase())
// LOG.info('Response Status Code: ' + httpResponse.code())
// LOG.info('Response: ' + httpResponse.bodyAsString())
//
// if (httpResponse.code() == 200) {
// if (httpResponse.bodyAsString().contains('SUCCESSFUL')) {
// response.setResult('ok')
// return
// } else {
//
// response.setSessionAttribute('agov.fido2.X-ReCAPTCHA-Integration', 'VISIBLE')
// response.setResult('exit.1')
// return
// }
// } else {
// LOG.error('Unexcpected HTTP response code: ' + httpResponse.code())
// response.setResult('error')
// response.setError(1, 'Unexpected HTTP reponse')
// }
// } catch (all) {
// // Handle exception and set the transition
// LOG.error('error: ' + all, all)
// response.setResult('error')
// response.setError(1, 'Exception during HTTP call')
// }
import io.opentelemetry.api.trace.Span
def url = parameters.get('url')
def email = inargs['userInputValue_prompt.email']
def token = inargs['captcha_response']?: 'MISSING'
def enabled = (session['agov.fido2.captchaSettings.enabled']?:'true').toBoolean()
def ip = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown'
def userAgent = request.getLoginContext()['connection.HttpHeader.user-agent'] ?: request.getLoginContext()['connection.HttpHeader.User-Agent'] ?: 'unknown'
def payload = "{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }"
LOG.debug('Token: ' + token)
LOG.debug('Payload: ' + payload)
try {
if (!enabled) {
LOG.info("FriendlyCAPTCHA is disabled, allowing operation for ${payload}")
response.setResult('ok')
return
}
def spanCtxt = Span.current().getSpanContext()
def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}"
def httpClient = HttpClients.create(parameters)
def httpResponse = Http.post()
.url(url)
.header("Accept", "application/json")
.header("X-FriendlyCAPTCHA-Token", token)
.header("traceparent", traceparent)
.entity(Http.entity()
.content(payload)
.contentType("application/json")
.build())
.build()
.send(httpClient)
LOG.debug('Response Status Code: ' + httpResponse.code())
LOG.debug('Response: ' + httpResponse.bodyAsString())
if (httpResponse.code() == 200) {
if (httpResponse.bodyAsString().contains('SUCCESSFUL')) {
response.setResult('ok')
return
} else {
LOG.warn("Friendly captcha not successful for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }'")
response.setResult('exit.1')
return
}
} else {
LOG.error("Friendly captcha failed with statuscode ${httpResponse.code()} for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }'")
response.setResult('error')
response.setError(1, 'Unexpected HTTP reponse')
}
} catch (all) {
// Handle exception and set the transition
LOG.error("Friendly captcha failed with a general error '${all}' for '{ \"userIp\": \"${ip}\", \"email\": \"${email}\", \"userAgent\": \"${userAgent}\" }', service-url: ${url}")
response.setResult('error')
response.setError(1, 'Exception during HTTP call')
}

View File

@ -1,7 +1,10 @@
import io.opentelemetry.api.trace.Span
def url = parameters.get('url')
def email = inargs['email']
def token = inargs['captcha_response']?: 'MISSING'
def enabled = (session['agov.recovery.captchaSettings.enabled']?:'true').toBoolean()
def ip = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown'
def userAgent = request.getLoginContext()['connection.HttpHeader.user-agent'] ?: request.getLoginContext()['connection.HttpHeader.User-Agent'] ?: 'unknown'
@ -13,11 +16,21 @@ LOG.debug('Payload: ' + payload)
try {
if (!enabled) {
LOG.info("FriendlyCAPTCHA is disabled, allowing operation for ${payload}")
response.setResult('ok')
return
}
def spanCtxt = Span.current().getSpanContext()
def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}"
def httpClient = HttpClients.create(parameters)
def httpResponse = Http.post()
.url(url)
.header("Accept", "application/json")
.header("X-FriendlyCAPTCHA-Token", token)
.header("traceparent", traceparent)
.entity(Http.entity()
.content(payload)
.contentType("application/json")
@ -25,7 +38,6 @@ try {
.build()
.send(httpClient)
LOG.debug('Response Message: ' + httpResponse.reasonPhrase())
LOG.debug('Response Status Code: ' + httpResponse.code())
LOG.debug('Response: ' + httpResponse.bodyAsString())
@ -49,54 +61,3 @@ try {
response.setResult('error')
response.setError(1, 'Exception during HTTP call')
}
// TODO/haburger/2024-AUG-20: remove if reCaptcha is not needed anymore
// def payload = '{ "email": "' + inargs['email'] + '", "action": "LOGIN", "userIp": "' + session.get('agov.recovery.ip') + '", "userAgent": "' + session.get('agov.recovery.userAgent') + '"}'
//
// LOG.info('Token: ' + inargs['recaptcha_response'])
// LOG.info('Integration: ' + session['agov.recovery.X-ReCAPTCHA-Integration'])
// LOG.info('Payload: ' + payload)
//
// try {
//
// def httpClient = HttpClients.create(parameters)
// def httpResponse = Http.post()
// .url(url)
// .header("Accept", "application/json")
// .header("X-ReCAPTCHA-Token", inargs['recaptcha_response'])
// .header("X-ReCAPTCHA-Integration", session['agov.recovery.X-ReCAPTCHA-Integration'])
// .entity(Http.entity()
// .content(payload)
// .contentType("application/json")
// // .charSet("utf-8")
// .build())
// .build()
// .send(httpClient)
//
// LOG.info('Response Message: ' + httpResponse.reasonPhrase())
// LOG.info('Response Status Code: ' + httpResponse.code())
// LOG.info('Response: ' + httpResponse.bodyAsString())
//
// if (httpResponse.code() == 200) {
// if (httpResponse.bodyAsString().contains('SUCCESSFUL')) {
// response.setResult('ok')
// return
// } else {
//
// response.setSessionAttribute('agov.recovery.X-ReCAPTCHA-Integration', 'VISIBLE')
// response.setResult('exit.1')
// return
// }
// } else {
// LOG.error('Unexcpected HTTP response code: ' + httpResponse.code())
// response.setResult('error')
// response.setError(1, 'Unexpected HTTP reponse')
// }
// } catch (all) {
// // Handle exception and set the transition
// LOG.error('error: ' + all, all)
// response.setResult('error')
// response.setError(1, 'Exception during HTTP call')
// }

View File

@ -1,41 +1,41 @@
//import ch.nevis.esauth.util.httpclient.api.HttpClient;
//import ch.nevis.esauth.util.httpclient.api.HttpClients;
//import ch.nevis.esauth.util.httpclient.api.Http;
def url = parameters.get('url')
//def payload = parameters.get('json')
//def url = "https://me.agov-d.azure.adnovum.net:48081/utility/api/v1/email/031"
def email = inargs['email']
def language = session['ch.nevis.session.user.language'] ?: 'en'
def payload = '{ "email": "' + email + '", "language": "' + language + '"}'
try {
def httpClient = HttpClients.create(parameters)
def httpResponse = Http.post()
.url(url)
.header("Accept", "application/json")
.entity(Http.entity()
.content(payload)
.contentType("application/json")
// .charSet("utf-8")
.build())
.build()
.send(httpClient)
LOG.info('Response Message: ' + httpResponse.reasonPhrase())
LOG.info('Response Status Code: ' + httpResponse.code())
LOG.info('Response: ' + httpResponse.bodyAsString())
if (httpResponse.code() == 200) {
response.setResult('ok')
} else {
LOG.error('Unexcpected HTTP response code: ' + httpResponse.code())
response.setResult('error')
response.setError(1, 'Unexpected HTTP reponse')
}
} catch (all) {
// Handle exception and set the transition
LOG.error('error: ' + all, all)
response.setResult('error')
response.setError(1, 'Exception during HTTP call')
import io.opentelemetry.api.trace.Span
def url = parameters.get('url')
def email = inargs['email']
def language = session['ch.nevis.session.user.language'] ?: 'en'
def payload = '{ "email": "' + email + '", "language": "' + language + '"}'
try {
def spanCtxt = Span.current().getSpanContext()
def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}"
def httpClient = HttpClients.create(parameters)
def httpResponse = Http.post()
.url(url)
.header("Accept", "application/json")
.header("traceparent", traceparent)
.entity(Http.entity()
.content(payload)
.contentType("application/json")
// .charSet("utf-8")
.build())
.build()
.send(httpClient)
LOG.info('Response Message: ' + httpResponse.reasonPhrase())
LOG.info('Response Status Code: ' + httpResponse.code())
LOG.info('Response: ' + httpResponse.bodyAsString())
if (httpResponse.code() == 200) {
response.setResult('ok')
} else {
LOG.error('Unexcpected HTTP response code: ' + httpResponse.code())
response.setResult('error')
response.setError(1, 'Unexpected HTTP reponse')
}
} catch (all) {
// Handle exception and set the transition
LOG.error('error: ' + all, all)
response.setResult('error')
response.setError(1, 'Exception during HTTP call')
}

View File

@ -1,18 +0,0 @@
schemaVersion: "1.0"
pattern:
id: "3cc9ad9d0cc771665881abcc"
className: "ch.nevis.admin.v4.plugin.nevisauth.patterns2.TransformVariablesStep"
name: "AuthnFailed_LockedAccount"
label: "UTILS"
notes: "Display screen : informing the user that a problem blocking his account\
\ has been encountered\n\nmissing info : if you didn't lock the account then go\
\ consult the support page for unlocking the account\n\nErrors : 1: user verification\
\ failed (user not found); 98: account disabled or archived (98 not in use yet)"
properties:
variables:
- notes:saml.errorCode: "urn:oasis:names:tc:SAML:2.0:status:AuthnFailed"
- notes:saml.errorMessage: "Your account is locked , Request ID: ${request:transferId}"
- notes:saml.errorInfo: "If you didn't lock the account then go consult the support\
\ page for unlocking the account"
onSuccess:
- "pattern://473f9d6b4ab9d61c1eb8c689"

View File

@ -1,13 +0,0 @@
schemaVersion: "1.0"
pattern:
id: "887ada57500885703a4a9408"
className: "ch.nevis.admin.v4.plugin.nevisauth.patterns2.TransformVariablesStep"
name: "FIDO2_ResetSessionInfos"
notes: "TODO/haburger/2024-AUG-20: remove after migration to Friendly Captcha is\
\ done"
properties:
variables:
- sess:agov.fido2.X-ReCAPTCHA-Integration: ""
emptyValue: "remove-variable"
onSuccess:
- "pattern://f39352769cb2a1c88e1a176d"

View File

@ -0,0 +1,9 @@
schemaVersion: "1.0"
pattern:
id: "2d8151249e6734ccc072422b"
className: "ch.nevis.admin.v4.plugin.nevisproxy.patterns.AutomaticTrustStoreProvider"
name: "IdP-Idm-SecToken-Signer-Trust"
properties:
keystore:
- "pattern://aeb2fed9962dcd5f7893db51"
truststoreFile: "var://idp-idm-sectoken-signer-trust-additional-trusted-certificates"

View File

@ -9,7 +9,7 @@ pattern:
onSuccess:
- "pattern://56c67433c7a47b6cb06f011a"
nextSteps:
- "pattern://887ada57500885703a4a9408"
- "pattern://f39352769cb2a1c88e1a176d"
- "pattern://d76231eaa88cb1645ce44cf3"
resources: "res://f63c475c35b616b7c6c1901c#resources"
keyObjects:

View File

@ -7,6 +7,7 @@ pattern:
scriptFile: "res://bea3ca0c85381d07d632be52#scriptFile"
parameters:
- url: "${var.captcha-service.configinfo.url}"
- realIpHttpHeaderName: "${var.captcha-service.configinfo.realIpHttpHeaderName}"
onSuccess:
- "pattern://584964c837512845d7940809"
scriptTraceGroup: "AgovCaptcha"

View File

@ -3,34 +3,6 @@ pattern:
id: "0d3511bed6798a78cc3237f6"
className: "ch.nevis.admin.v4.plugin.nevisproxy.patterns.SecurityResponseHeaders"
name: "Security Response Headers"
label: "PROXY"
properties:
responseHeaders:
- Strict-Transport-Security: "max-age=63072000; includeSubDomains;"
- X-Content-Type-Options: "nosniff"
- Referrer-Policy: "strict-origin-when-cross-origin"
- X-Frame-Options: "DENY"
- Cross-Origin-Opener-Policy: "same-origin"
- Cross-Origin-Embedder-Policy: "require-corp"
- Cross-Origin-Resource-Policy: "same-site"
- Permissions-Policy: "geolocation=(), camera=(), microphone=(), interest-cohort=()"
- Content-Security-Policy-Report-Only: "default-src 'none'; script-src 'self'\
\ 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM=' 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM='\
\ 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM=' 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM='\
\ 'unsafe-inline'; script-src-elem https://www.google.com https://www.gstatic.com\
\ 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM=' 'sha256-VVRbrI9TGfTX6IQoysg2+krJFUO9Ckt6G7Gcs1q2dgM='\
\ 'sha256-6FA//NVJWFgnJwirzDKHC42MZIXYrIxtNaKCahX3DLg=' 'sha256-3whVsWq2brmbgJQdoqbeJgW+43c+XyGdWbKl7sqG3YQ='\
\ 'sha256-3whVsWq2brmbgJQdoqbeJgW+43c+XyGdWbKl7sqG3YQ=' 'self'; connect-src\
\ 'self'; img-src 'self'; style-src 'self' 'sha256-Q5DmyIIE+GwAh03yBzctDxvuwMTX0uUUUP5UU3yFoF0='\
\ 'sha256-Q5DmyIIE+GwAh03yBzctDxvuwMTX0uUUUP5UU3yFoF0=' 'sha256-JnkgaYe2Kqj0SvIYv1vTPV72Rnsp5aU6c015YNij5Ks='\
\ 'sha256-jRcpQ00xp7HFefM8uuubCrmPgr9Q/zMqq+Be8IyLXyM=' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='\
\ 'sha256-MdFWcEIx4V82/ap9SUt01BxZMN4eFGEl8hNDFEGIzJU=' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='\
\ 'sha256-ifPclQYYwRDXSPQgB9/6UgAgEICBpwegJBWNhOI8dOA=' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='\
\ 'sha256-2diQqrANllVP9IWjXj1A6fjjvlPtpN6NXlmTiRJneCU=' 'sha256-Q5DmyIIE+GwAh03yBzctDxvuwMTX0uUUUP5UU3yFoF0='\
\ 'sha256-Q5DmyIIE+GwAh03yBzctDxvuwMTX0uUUUP5UU3yFoF0=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\
\ 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\
\ 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\
\ 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\
\ 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\
\ 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE=' 'sha256-ZdHxw9eWtnxUb3mk6tBS+gIiVUPE3pGM470keHPDFlE='\
\ 'unsafe-hashes' 'unsafe-inline'; form-action 'self'; font-src 'self'; frame-src\
\ https://www.google.com"
responseHeaders: "var://security-response-headers-response-headers"

View File

@ -1,44 +0,0 @@
import groovy.json.JsonSlurper
def url = parameters.get('url')
try {
def jsonSlurper = new JsonSlurper()
def httpClient = HttpClients.create(parameters)
def httpResponse = Http.get().url(url).build().send(httpClient)
LOG.debug('Response Message: ' + httpResponse.reasonPhrase())
LOG.debug('Response Status Code: ' + httpResponse.code())
LOG.debug('Response: ' + httpResponse.bodyAsString())
if (httpResponse.code() == 200) {
def json = jsonSlurper.parseText(httpResponse.bodyAsString())
// TODO/haburger/2024-AUG-20: remove if reCaptcha is not needed anymore
// response.setSessionAttribute('agov.recovery.json.accountUrl', json.accountUrl)
// response.setSessionAttribute('agov.recovery.json.registrationUrl', json.registrationUrl)
// response.setSessionAttribute('agov.recovery.json.captchaSettings.enabled', String.valueOf(json.captchaSettings.enabled))
// response.setSessionAttribute('agov.recovery.json.captchaSettings.reCaptchaInvisibleSiteKey', json.captchaSettings.reCaptchaInvisibleSiteKey)
// response.setSessionAttribute('agov.recovery.json.captchaSettings.reCaptchaVisibleSiteKey', json.captchaSettings.reCaptchaVisibleSiteKey)
// if (session.get('agov.recovery.X-ReCAPTCHA-Integration') == null) {
// response.setSessionAttribute('agov.recovery.X-ReCAPTCHA-Integration', 'INVISIBLE')
// } else {
// response.setSessionAttribute('agov.recovery.X-ReCAPTCHA-Integration', 'VISIBLE')
// }
response.setSessionAttribute('agov.recovery.captchaSettings.enabled', String.valueOf(json.captchaSettings.enabled))
response.setSessionAttribute('agov.recovery.captchaSettings.siteKey', json.friendlyCaptureClientSettings.siteKey)
response.setSessionAttribute('agov.recovery.captchaSettings.puzzleUrl', json.friendlyCaptureClientSettings.puzzleUrl)
response.setResult('ok')
} else {
LOG.error('Unexcpected HTTP response code: ' + httpResponse.code())
response.setResult('error')
response.setError(1, 'Unexpected HTTP reponse')
}
} catch (all) {
// Handle exception and set the transition
LOG.error('error: ' + all, all)
response.setResult('error')
response.setError(1, 'Exception during HTTP call')
}

View File

@ -0,0 +1,39 @@
import groovy.json.JsonSlurper
import io.opentelemetry.api.trace.Span
def url = parameters.get('url')
def realIpHttpHeaderName = parameters.get('realIpHttpHeaderName') ?: 'X-Real-IP'
def ip = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown'
try {
def spanCtxt = Span.current().getSpanContext()
def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}"
def jsonSlurper = new JsonSlurper()
def httpClient = HttpClients.create(parameters)
def httpResponse = Http.get().url(url).header('traceparent', traceparent)
.header(realIpHttpHeaderName, ip).build().send(httpClient)
LOG.debug('Response Status Code: ' + httpResponse.code())
LOG.debug('Response: ' + httpResponse.bodyAsString())
if (httpResponse.code() == 200) {
def json = jsonSlurper.parseText(httpResponse.bodyAsString())
response.setSessionAttribute('agov.recovery.captchaSettings.enabled', String.valueOf(json.friendlyCaptureClientSettings.enabled))
response.setSessionAttribute('agov.recovery.captchaSettings.siteKey', json.friendlyCaptureClientSettings.siteKey)
response.setSessionAttribute('agov.recovery.captchaSettings.puzzleUrl', json.friendlyCaptureClientSettings.puzzleUrl)
response.setResult('ok')
} else {
LOG.error('Unexcpected HTTP response code: ' + httpResponse.code())
response.setResult('error')
response.setError(1, 'Unexpected HTTP reponse')
}
} catch (all) {
// Handle exception and set the transition
LOG.error('error: ' + all, all)
response.setResult('error')
response.setError(1, 'Exception during HTTP call')
}

View File

@ -1,4 +1,5 @@
import ch.nevis.esauth.auth.engine.AuthResponse
if (inargs['cancel'] == 'cancel') {
//cleanSession()
response.setStatus(AuthResponse.AUTH_ERROR)

View File

@ -8,12 +8,6 @@
<GuiElem name="authRequestId" type="hidden" value="${sess:ch.nevis.auth.saml.request.id}" optional="true"/>
<GuiElem name="email" type="text" label="prompt.email" value="#{(inargs.getProperty('userInputValue_prompt.email') != null) ? inargs.getProperty('userInputValue_prompt.email') : session.get('ch.nevis.idm.User.email')}" optional="true"/>
<GuiElem name="captchaSettings.enabled" type="hidden" value="${sess:agov.fido2.captchaSettings.enabled}" optional="true"/>
<!-- TODO/haburger/2024-AUG-20: remove Google after successfull migration to Friendly Captcha -->
<!-- <GuiElem name="captchaSettings.reCaptchaInvisibleSiteKey" type="hidden" value="${sess:agov.fido2.json.captchaSettings.reCaptchaInvisibleSiteKey}" optional="true"/> -->
<!-- <GuiElem name="captchaSettings.reCaptchaVisibleSiteKey" type="hidden" value="${sess:agov.fido2.json.captchaSettings.reCaptchaVisibleSiteKey}" optional="true"/> -->
<!-- <GuiElem name="X-ReCAPTCHA-Integration" type="hidden" value="${sess:agov.fido2.X-ReCAPTCHA-Integration}" optional="true"/> -->
<GuiElem name="friendlyCaptchaSettings.siteKey" type="hidden" value="${sess:agov.fido2.captchaSettings.siteKey}" optional="true"/>
<GuiElem name="friendlyCaptchaSettings.puzzleUrl" type="hidden" value="${sess:agov.fido2.captchaSettings.puzzleUrl}" optional="true"/>

View File

@ -5,9 +5,9 @@
<Response value="AUTH_CONTINUE"/>
<property name="scriptTraceGroup" value="AGOV-ACCT"/>
<property name="script" value="file:///var/opt/nevisauth/default/conf/ensureAccountState.groovy"/>
<property name="parameter.idm.baseUrl" value="https://${param.idm-service:idm}:8989/nevisidm/api"/>
<property name="parameter.unitExtid" value="${param.agov.unitExtId:9907b8d4-a0cb-4028-a850-03efadbc73ad}"/>
<property name="parameter.level100.roleExtid" value="${param.agov.level100.roleExtid:aee52e9f-7084-4e55-9aea-9383ac7757f7}"/>
<property name="parameter.idm.baseUrl" value="https://${param.idm-service}:8989/nevisidm/api"/>
<property name="parameter.unitExtid" value="${param.agov.unitExtId}"/>
<property name="parameter.level100.roleExtid" value="${param.agov.level100.roleExtid}"/>
<property name="parameter.idm.httpclient.tls.trustStoreRef" value="Ensure_Account_State"/>
</AuthState>
<AuthState name="${state.entry}_Reload" final="false" class="ch.nevis.idm.authstate.IdmGetPropertiesState" resumeState="false">

View File

@ -94,12 +94,13 @@ if (!session['ch.adnovum.nevisidm.userDto'].contains("<properties><name>idVerifi
json['items'].eachWithIndex { az, i ->
if (az.roleExtId == level100RoleExtid) {
agovAq100AuthEndpoint = "${endpoint}/${az.extId}"
aq100AuthRestURL = "${endpoint}/${az.extId}"
}
}
}
endpoint = "${aq100AuthRestURL}/properties"
endpoint = "${aq100AuthRestURL}/properties"
def patchRequest = new HTTPRequestWrapper()
patchRequest.addToHeaders('Content-Type', ['application/json'])

View File

@ -1,52 +1,38 @@
import groovy.json.JsonSlurper
import io.opentelemetry.api.trace.Span
def url = parameters.get('url')
try {
//TODO/haburger/2024-AUG-20: remove if reCaptcha is not needed anymore
session.remove('agov.fido2.X-ReCAPTCHA-Integration')
def spanCtxt = Span.current().getSpanContext()
def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}"
LOG.error('traceparent: ' + traceparent)
def jsonSlurper = new JsonSlurper()
def httpClient = HttpClients.create(parameters)
def httpResponse = Http.get().url(url).build().send(httpClient)
LOG.debug('Response Message: ' + httpResponse.reasonPhrase())
LOG.debug('Response Status Code: ' + httpResponse.code())
LOG.debug('Response: ' + httpResponse.bodyAsString())
if (httpResponse.code() == 200) {
def json = jsonSlurper.parseText(httpResponse.bodyAsString())
// TODO/haburger/2024-AUG-20: remove if reCaptcha is not needed anymore
// response.setSessionAttribute('agov.fido2.json.captchaSettings.enabled', String.valueOf(json.captchaSettings.enabled))
// response.setSessionAttribute('agov.fido2.json.captchaSettings.reCaptchaInvisibleSiteKey', json.captchaSettings.reCaptchaInvisibleSiteKey)
// response.setSessionAttribute('agov.fido2.json.captchaSettings.reCaptchaVisibleSiteKey', json.captchaSettings.reCaptchaVisibleSiteKey)
//
// if (session.get('agov.fido2.X-ReCAPTCHA-Integration') == null) {
// response.setSessionAttribute('agov.fido2.X-ReCAPTCHA-Integration', 'INVISIBLE')
// } else {
// response.setSessionAttribute('agov.fido2.X-ReCAPTCHA-Integration', 'VISIBLE')
// }
response.setSessionAttribute('agov.fido2.captchaSettings.enabled', String.valueOf(json.friendlyCaptureClientSettings.enabled))
response.setSessionAttribute('agov.fido2.captchaSettings.siteKey', json.friendlyCaptureClientSettings.siteKey)
response.setSessionAttribute('agov.fido2.captchaSettings.puzzleUrl', json.friendlyCaptureClientSettings.puzzleUrl)
response.setResult('ok')
} else {
LOG.error('Unexcpected HTTP response code: ' + httpResponse.code())
response.setResult('error')
response.setError(1, 'Unexpected HTTP reponse')
}
} catch (all) {
// Handle exception and set the transition
LOG.error('error: ' + all, all)
response.setResult('error')
response.setError(1, 'Exception during HTTP call')
import groovy.json.JsonSlurper
import io.opentelemetry.api.trace.Span
def url = parameters.get('url')
def realIpHttpHeaderName = parameters.get('realIpHttpHeaderName') ?: 'X-Real-IP'
def ip = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown'
try {
def spanCtxt = Span.current().getSpanContext()
def traceparent = "00-${spanCtxt.getTraceId()}-${spanCtxt.getSpanId()}-${spanCtxt.getTraceFlags().asHex()}"
def jsonSlurper = new JsonSlurper()
def httpClient = HttpClients.create(parameters)
def httpResponse = Http.get().url(url).header('traceparent', traceparent)
.header(realIpHttpHeaderName, ip).build().send(httpClient)
LOG.debug('Response Status Code: ' + httpResponse.code())
LOG.debug('Response: ' + httpResponse.bodyAsString())
if (httpResponse.code() == 200) {
def json = jsonSlurper.parseText(httpResponse.bodyAsString())
response.setSessionAttribute('agov.fido2.captchaSettings.enabled', String.valueOf(json.friendlyCaptureClientSettings.enabled))
response.setSessionAttribute('agov.fido2.captchaSettings.siteKey', json.friendlyCaptureClientSettings.siteKey)
response.setSessionAttribute('agov.fido2.captchaSettings.puzzleUrl', json.friendlyCaptureClientSettings.puzzleUrl)
response.setResult('ok')
} else {
LOG.error('Unexcpected HTTP response code: ' + httpResponse.code())
response.setResult('error')
response.setError(1, 'Unexpected HTTP reponse')
}
} catch (all) {
// Handle exception and set the transition
LOG.error('error: ' + all, all)
response.setResult('error')
response.setError(1, 'Exception during HTTP call')
}

View File

@ -7,6 +7,7 @@ pattern:
scriptFile: "res://f39352769cb2a1c88e1a176d#scriptFile"
parameters:
- url: "${var.captcha-service.configinfo.url}"
- realIpHttpHeaderName: "${var.captcha-service.configinfo.realIpHttpHeaderName}"
onSuccess:
- "pattern://e3cac41e75980361d7d26bde"
onFailure:

View File

@ -14,3 +14,4 @@ pattern:
user: "var://auth-session-store-database-user"
password: "var://auth-session-store-database-password"
databaseManagement: "var://auth-session-store-database-management"
parameters: "serverTimezone=UTC"

View File

@ -10,7 +10,7 @@ pattern:
frontendTrustStore:
- "pattern://c0722fc79e7314c9cdcd20ff"
authSignerTrustStore:
- "pattern://55bf63a1b1716e9631f7080d"
- "pattern://2d8151249e6734ccc072422b"
database:
- "pattern://2951ead44a7a9362a4545094"
logging:

View File

@ -450,6 +450,12 @@ variables:
value: "cors.allowed.fqdns: '{\"trustbroker.agov-d.azure.adnovum.net\", \"auth.agov-d.azure.adnovum.net\"\
}'"
requireOverloading: true
idp-idm-sectoken-signer-trust-additional-trusted-certificates:
className: "ch.nevis.admin.v4.plugin.base.generation.property.AttachmentProperty"
parameters:
minRequired: 0
value: null
requireOverloading: true
idp-sp-connector-properties:
className: "ch.nevis.admin.v4.plugin.base.generation.property.AuthStateProperty"
parameters:
@ -571,7 +577,8 @@ variables:
separators:
- "="
switchedSeparators: []
value: null
value:
- OpTrace: "DEBUG"
requireOverloading: true
log_idm-default-log-level:
className: "ch.nevis.admin.v4.plugin.base.generation.property.SelectionProperty"
@ -883,6 +890,31 @@ variables:
secret: true
value: "sample password"
requireOverloading: true
security-response-headers-response-headers:
className: "ch.nevis.admin.v4.plugin.base.generation.property.KeyValueProperty"
parameters:
minRequired: 1
separators:
- ":"
switchedSeparators: []
value:
- Strict-Transport-Security: "max-age=63072000; includeSubDomains;"
- X-Content-Type-Options: "nosniff"
- Referrer-Policy: "strict-origin-when-cross-origin"
- X-Frame-Options: "DENY"
- Cross-Origin-Opener-Policy: "same-origin"
- Cross-Origin-Embedder-Policy: "require-corp"
- Cross-Origin-Resource-Policy: "same-site"
- Permissions-Policy: "geolocation=(), camera=(), microphone=(), interest-cohort=()"
- Content-Security-Policy-Report-Only: "default-src 'none'; script-src 'self'\
\ 'sha256-YPbtYpCQA51uSiLa2ux1TkGQoRDNbpdlYd50ospNgYw=' 'sha256-YPbtYpCQA51uSiLa2ux1TkGQoRDNbpdlYd50ospNgYw='\
\ 'sha256-uOoE0nq21NJDv37YLUOxV9aCnNstJ0GK7BiXNMXQAcI='; connect-src 'self';\
\ img-src 'self'; style-src 'self' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='\
\ 'sha256-MdFWcEIx4V82/ap9SUt01BxZMN4eFGEl8hNDFEGIzJU=' 'sha256-ifPclQYYwRDXSPQgB9/6UgAgEICBpwegJBWNhOI8dOA='\
\ 'sha256-2diQqrANllVP9IWjXj1A6fjjvlPtpN6NXlmTiRJneCU=' 'sha256-JhfXJ5URuB/EAqhZ9vqgEO6trOuCE0w2/ChmfrVzxFo=';\
\ form-action 'self' https://trustbroker.agov-d.azure.adnovum.net/adfs/ls;\
\ font-src 'self'; "
requireOverloading: true
service_provider_state-registration-template-parameters:
className: "ch.nevis.admin.v4.plugin.base.generation.property.TextProperty"
parameters: