feature/Handle Consent Header Inalid Value

This commit is contained in:
Marko Milić 2022-12-19 15:25:53 +01:00
parent bd9f76cbca
commit 7534296b24
6 changed files with 33 additions and 8 deletions

View File

@ -2762,11 +2762,16 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
Consent.applyBerlinGroupRules(APIUtil.`getConsent-ID`(reqHeaders), cc)
} else if (APIUtil.hasConsentJWT(reqHeaders)) { // Open Bank Project's Consent
val consentValue = APIUtil.getConsentJWT(reqHeaders)
Consent.getConsentsJwtValueByConsentId(consentValue.getOrElse("")) match {
Consent.getConsentJwtValueByConsentId(consentValue.getOrElse("")) match {
case Some(jwt) => // JWT value obtained via "Consent-Id" request header
Consent.applyRules(Some(jwt), cc)
case _ => // Assume it's JWT obtained via "Consent-JWT" request header
Consent.applyRules(APIUtil.getConsentJWT(reqHeaders), cc)
case _ =>
JwtUtil.checkIfStringIsJWTValue(consentValue.getOrElse("")).isDefined match {
case true => // It's JWT obtained via "Consent-JWT" request header
Consent.applyRules(APIUtil.getConsentJWT(reqHeaders), cc)
case false => // Unrecognised consent value
Future { (Failure(ErrorMessages.ConsentHeaderValueInvalid), None) }
}
}
} else if (hasAnOAuthHeader(cc.authReqHeaderField)) { // OAuth 1
getUserFromOAuthHeaderFuture(cc)
@ -3488,8 +3493,11 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
* This function validates UUID (Universally Unique Identifier) strings
* @param value a string we're trying to validate
* @return false in case the string doesn't represent a UUID, true in case the string represents a UUID
*
*A Version 1 UUID is a universally unique identifier that is generated using
* a timestamp and the MAC address of the computer on which it was generated.
*/
def checkIfStringIsUUID(value: String): Boolean = {
def checkIfStringIsUUIDVersion1(value: String): Boolean = {
Pattern.compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$")
.matcher(value).matches()
}

View File

@ -380,8 +380,8 @@ object Consent {
}
}
def getConsentsJwtValueByConsentId(consentId: String): Option[String] = {
APIUtil.checkIfStringIsUUID(consentId) match {
def getConsentJwtValueByConsentId(consentId: String): Option[String] = {
APIUtil.checkIfStringIsUUIDVersion1(consentId) match {
case true => // String is a UUID
Consents.consentProvider.vend.getConsentByConsentId(consentId) match {
case Full(consent) => Some(consent.jsonWebToken)

View File

@ -502,6 +502,7 @@ object ErrorMessages {
val ConsentRequestIsInvalid = "OBP-35029: The CONSENT_REQUEST_ID is invalid. "
val ConsumerKeyIsInvalid = "OBP-35030: The Consumer Key must be alphanumeric. (A-Z, a-z, 0-9)"
val ConsumerKeyIsToLong = "OBP-35031: The Consumer Key max length <= 512"
val ConsentHeaderValueInvalid = "OBP-35032: The Consent's Request Header value is not formatted as UUID or JWT."
//Authorisations
val AuthorisationNotFound = "OBP-36001: Authorisation not found. Please specify valid values for PAYMENT_ID and AUTHORISATION_ID. "

View File

@ -19,6 +19,16 @@ import net.liftweb.common.{Box, Empty, Failure, Full}
object JwtUtil extends MdcLoggable {
def checkIfStringIsJWTValue(jwtToken: String): Box[String] = {
try {
val signedJWT: SignedJWT = SignedJWT.parse(jwtToken)
Full(signedJWT.toString())
} catch {
case e: Exception =>
Failure(e.getMessage())
}
}
def getSignedPayloadAsJson(jwtToken: String): Box[String] = {
try {
val signedJWT = SignedJWT.parse(jwtToken)

View File

@ -3678,7 +3678,7 @@ trait APIMethods310 {
| - You as the service provider have determined an application is compromised or malicious, and want to disable it
| - etc.
|
|Please note that this endpoint oly supports the case: "The user explicitly wishes to revoke the applications access"
|Please note that this endpoint only supports the case:: "The user explicitly wishes to revoke the applications access"
|
|OBP as a resource server stores access tokens in a database, then it is relatively easy to revoke some token that belongs to a particular user.
|The status of the token is changed to "REVOKED" so the next time the revoked client makes a request, their token will fail to validate.

View File

@ -150,8 +150,14 @@ class ConsentRequestTest extends V500ServerSetupAsync with PropsReset{
responseGetUsersSecond.code should equal(200)
val usersSecond = responseGetUsersSecond.body.extract[UsersJsonV400].users
usersSecond.size should be > 0
users.size should equal(usersSecond.size)
// Test Request Header "Consent-JWT:INVALID_JWT_VALUE"
val wrongRequestHeader = (s"Consent-JWT", "INVALID_JWT_VALUE")
val responseGetUsersWrong = makeGetRequest(requestGetUsers, List(wrongRequestHeader))
Then("We get successful response")
responseGetUsersWrong.code should equal(401)
responseGetUsersWrong.body.extract[ErrorMessage].message contains (ConsentHeaderValueInvalid) should be (true)
}
}