129 lines
6.2 KiB
Groovy
129 lines
6.2 KiB
Groovy
import groovy.xml.XmlSlurper
|
|
import groovy.json.JsonSlurper
|
|
import io.opentelemetry.api.trace.Span
|
|
|
|
int getRequestedLevel(String authnContextClassRef, def roleList){
|
|
if (!authnContextClassRef) {
|
|
return 100
|
|
}
|
|
if (authnContextClassRef && authnContextClassRef.startsWith('urn:qa.agov.ch:names:tc:ac:classes:')) {
|
|
def requestedLevel = authnContextClassRef.substring(35)
|
|
LOG.debug('authnContextClassRef agov found: ' + requestedLevel)
|
|
if (requestedLevel.isNumber()) {
|
|
int requestedLevelNumber = Integer.parseInt(requestedLevel)
|
|
LOG.debug('contains ' + roleList.contains(requestedLevelNumber))
|
|
if (requestedLevel.isNumber() && roleList.contains(requestedLevelNumber)) {
|
|
LOG.debug('Requested role number: ' + requestedLevel)
|
|
return requestedLevelNumber
|
|
}
|
|
}
|
|
else return 0
|
|
}
|
|
else {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
def session = request.getAuthSession(true)
|
|
def context = session.get('ch.nevis.auth.saml.request.authnContextClassRef')
|
|
def roleLevels = [100,200,300,400]
|
|
def requestedRoleLevelNumber = getRequestedLevel(context, roleLevels)
|
|
|
|
//set attribute Requested Role Level
|
|
session.setAttribute('agov.requestedRoleLevel', '' + requestedRoleLevelNumber)
|
|
LOG.debug('Requested role level (agov) '+ requestedRoleLevelNumber)
|
|
|
|
// SAML finisherstate is now available, we can backup it
|
|
session.setAttribute('agov.backup.finishers', '' + session.getAttribute('ch.nevis.session.finishers'))
|
|
|
|
// Accounting
|
|
def requester = session['ch.nevis.auth.saml.request.scoping.requesterId'] ?: 'unknown'
|
|
def requestId = session['ch.nevis.auth.saml.request.id'] ?: 'unknown'
|
|
def replacedRequestId = session['agov.replacedRequestId'] ?: '-'
|
|
def requestedAq = session['agov.requestedRoleLevel'] ?: 'unknown'
|
|
def sourceIp = request.getLoginContext()['connection.HttpHeader.X-Real-IP'] ?: 'unknown'
|
|
def userAgent = request.getLoginContext()['connection.HttpHeader.user-agent'] ?: request.getLoginContext()['connection.HttpHeader.User-Agent'] ?: 'unknown'
|
|
|
|
LOG.info("Event='AUTHREQUEST', Requester='${requester}', RequestId='${requestId}', ReplacedRequestId='${replacedRequestId}', RequestedAq=${requestedAq}, SourceIp=${sourceIp}, UserAgent='${userAgent}'")
|
|
|
|
|
|
def appAddressRequiredWhitelist = ',' + (parameters.get('appAddressRequired.whitelist') ?: '').replaceAll('\\s','') + ','
|
|
def appIsOnappAddressRequiredWhitelist = appAddressRequiredWhitelist.contains(','+requester+',')
|
|
|
|
if (requestedRoleLevelNumber == 0 || session.get('ch.nevis.auth.saml.request.scoping.requesterId') == null) {
|
|
response.setResult('error');
|
|
return
|
|
}
|
|
|
|
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).header('traceparent', traceparent).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())
|
|
LOG.debug('AdressRequired: ' + json.addrRequired)
|
|
LOG.debug('SvnrAllowed: ' + json.svnrAllowed)
|
|
LOG.debug('appAddressRequiredWhitelist applies: ' + appIsOnappAddressRequiredWhitelist)
|
|
|
|
// address will be returned to the application if allowed by connect (json.addrRequired)
|
|
// and the authRequest was done with at least AGOVaq 200
|
|
// BITBKAGOVSUP-362: or whitelisted to receive the address
|
|
session.setAttribute('agov.appAddressRequired', '' + (json.addrRequired && ((requestedRoleLevelNumber >= 200) || appIsOnappAddressRequiredWhitelist)))
|
|
|
|
// address will be returned to the application if allowed by connect (json.svnrAllowed)
|
|
// and the authRequest was done with at least AGOVaq 300
|
|
session.setAttribute('agov.appSvnrAllowed', '' + (json.svnrAllowed && requestedRoleLevelNumber >= 300))
|
|
|
|
session.setAttribute('agov.appDisplayNameDE', '' + json.displayNameDe)
|
|
session.setAttribute('agov.appDisplayNameFR', '' + json.displayNameFr)
|
|
session.setAttribute('agov.appDisplayNameIT', '' + json.displayNameIt)
|
|
session.setAttribute('agov.appDisplayNameEN', '' + json.displayNameEn)
|
|
response.setResult('ok')
|
|
return
|
|
} else {
|
|
LOG.warn("Failed to fetch connect meta data for relying party '${session.get('ch.nevis.auth.saml.request.scoping.requesterId')}'")
|
|
LOG.warn('Unexcpected HTTP response code: ' + httpResponse.code())
|
|
|
|
if ( requestedRoleLevelNumber == 100) {
|
|
session.setAttribute('agov.appAddressRequired', '' + appIsOnappAddressRequiredWhitelist)
|
|
session.setAttribute('agov.appSvnrAllowed', 'false')
|
|
response.setResult('ok')
|
|
}
|
|
else if ( requestedRoleLevelNumber == 200) {
|
|
session.setAttribute('agov.appAddressRequired', 'true')
|
|
session.setAttribute('agov.appSvnrAllowed', 'false')
|
|
response.setResult('ok')
|
|
}
|
|
else {
|
|
response.setResult('error')
|
|
response.setError(9071, "Missing meta data for relying party, can't process request")
|
|
}
|
|
return
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
LOG.error("Failed to fetch connect meta data for relying party '${session.get('ch.nevis.auth.saml.request.scoping.requesterId')}'", e)
|
|
if ( requestedRoleLevelNumber == 100) {
|
|
session.setAttribute('agov.appAddressRequired', '' + appIsOnappAddressRequiredWhitelist)
|
|
session.setAttribute('agov.appSvnrAllowed', 'false')
|
|
response.setResult('ok')
|
|
}
|
|
else if ( requestedRoleLevelNumber == 200) {
|
|
session.setAttribute('agov.appAddressRequired', 'true')
|
|
session.setAttribute('agov.appSvnrAllowed', 'false')
|
|
response.setResult('ok')
|
|
}
|
|
else {
|
|
response.setResult('error')
|
|
response.setError(9072, "Failure while processing meta data for relying party, can't continue processing request")
|
|
}
|
|
return
|
|
} |