mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 13:07:02 +00:00
Merge pull request #2489 from constantine2nd/develop
Enable customer identification via TPP-Signature-Certificate
This commit is contained in:
commit
1a083c50d2
@ -664,7 +664,7 @@ where the consent was directly managed between ASPSP and PSU e.g. in a re-direct
|
||||
"lastActionDate": "2019-06-30",
|
||||
"consentStatus": "received"
|
||||
}"""),
|
||||
List(UserNotLoggedIn, UnknownError),
|
||||
List(UserNotLoggedIn, ConsentNotFound, UnknownError),
|
||||
ApiTag("Account Information Service (AIS)") :: apiTagBerlinGroupM :: Nil
|
||||
)
|
||||
|
||||
@ -672,11 +672,14 @@ where the consent was directly managed between ASPSP and PSU e.g. in a re-direct
|
||||
case "consents" :: consentId :: Nil JsonGet _ => {
|
||||
cc =>
|
||||
for {
|
||||
(Full(u), callContext) <- authenticatedAccess(cc)
|
||||
(_, callContext) <- applicationAccess(cc)
|
||||
_ <- passesPsd2Aisp(callContext)
|
||||
consent <- Future(Consents.consentProvider.vend.getConsentByConsentId(consentId)) map {
|
||||
unboxFullOrFail(_, callContext, s"$ConsentNotFound ($consentId)")
|
||||
}
|
||||
}
|
||||
_ <- Helper.booleanToFuture(failMsg = s"${consent.mConsumerId.get} != ${cc.consumer.map(_.consumerId.get).getOrElse("None")}", failCode = 404, cc = cc.callContext) {
|
||||
consent.mConsumerId.get == callContext.map(_.consumer.map(_.consumerId.get).getOrElse("None")).getOrElse("None")
|
||||
}
|
||||
} yield {
|
||||
(createGetConsentResponseJson(consent), HttpCode.`200`(callContext))
|
||||
}
|
||||
|
||||
@ -144,7 +144,9 @@ object RequestHeader {
|
||||
final lazy val `Consent-JWT` = "Consent-JWT"
|
||||
final lazy val `PSD2-CERT` = "PSD2-CERT"
|
||||
final lazy val `If-None-Match` = "If-None-Match"
|
||||
final lazy val `TPP-Redirect-URL` = "TPP-Redirect-URL"
|
||||
final lazy val `TPP-Redirect-URL` = "TPP-Redirect-URL" // Berlin Group
|
||||
final lazy val `TPP-Signature-Certificate` = "TPP-Signature-Certificate" // Berlin Group
|
||||
final lazy val `X-Request-ID` = "X-Request-ID" // Berlin Group
|
||||
/**
|
||||
* The If-Modified-Since request HTTP header makes the request conditional:
|
||||
* the server sends back the requested resource, with a 200 status,
|
||||
|
||||
@ -255,6 +255,16 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Purpose of this helper function is to get the PSD2-CERT value from a Request Headers.
|
||||
* @return the PSD2-CERT value from a Request Header as a String
|
||||
*/
|
||||
def getTppSignatureCertificate(requestHeaders: List[HTTPParam]): Option[String] = {
|
||||
requestHeaders.toSet.filter(_.name == RequestHeader.`TPP-Signature-Certificate`).toList match {
|
||||
case x :: Nil => Some(x.values.mkString(", "))
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
def getRequestHeader(name: String, requestHeaders: List[HTTPParam]): String = {
|
||||
requestHeaders.toSet.filter(_.name.toLowerCase == name.toLowerCase).toList match {
|
||||
@ -2983,6 +2993,9 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
|
||||
|
||||
val authHeaders = AuthorisationUtil.getAuthorisationHeaders(reqHeaders)
|
||||
|
||||
// Identify consumer via certificate
|
||||
val consumerByCertificate = Consent.getCurrentConsumerViaMtls(callContext = cc)
|
||||
|
||||
val res =
|
||||
if (authHeaders.size > 1) { // Check Authorization Headers ambiguity
|
||||
Future { (Failure(ErrorMessages.AuthorizationHeaderAmbiguity + s"${authHeaders}"), None) }
|
||||
@ -3109,7 +3122,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
|
||||
// - Authorization: Basic mF_9.B5f-4.1JqM
|
||||
Future { (Failure(ErrorMessages.InvalidAuthorizationHeader), Some(cc)) }
|
||||
} else {
|
||||
Future { (Empty, Some(cc)) }
|
||||
Future { (Empty, Some(cc.copy(consumer = consumerByCertificate))) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -128,9 +128,10 @@ object Consent extends MdcLoggable {
|
||||
* @return the boxed Consumer
|
||||
*/
|
||||
def getCurrentConsumerViaMtls(callContext: CallContext): Box[Consumer] = {
|
||||
val clientCert: String = APIUtil.`getPSD2-CERT`(callContext.requestHeaders)
|
||||
.getOrElse(SecureRandomUtil.csprng.nextLong().toString)
|
||||
|
||||
val clientCert: String = APIUtil.`getPSD2-CERT`(callContext.requestHeaders) // MTLS certificate QWAC (Qualified Website Authentication Certificate)
|
||||
.orElse(APIUtil.getTppSignatureCertificate(callContext.requestHeaders)) // Signature certificate QSealC (Qualified Electronic Seal Certificate)
|
||||
.getOrElse(SecureRandomUtil.csprng.nextLong().toString) // Force to fail
|
||||
|
||||
{ // 1st search is via the original value
|
||||
logger.debug(s"getConsumerByPemCertificate ${clientCert}")
|
||||
Consumers.consumers.vend.getConsumerByPemCertificate(clientCert)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user