mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 13:46:49 +00:00
feature/Yahoo as an OpenID Connect provider
This commit is contained in:
parent
92a29971e6
commit
48f2d28793
14
README.md
14
README.md
@ -468,7 +468,7 @@ There are 3 API's endpoint related to webhooks:
|
||||
## OpenID Connect
|
||||
In order to enable an OIDC workflow at an instance of OBP-API portal app(login functionality) you need to set-up the following props:
|
||||
```props
|
||||
# Google as an identity provider
|
||||
## Google as an identity provider
|
||||
# openid_connect_1.client_secret=OYdWujJl******_NXzPlDI4T
|
||||
# openid_connect_1.client_id=883**3244***-s4hi72j0rble0iiivq1gn09k7***tdci.apps.googleusercontent.com
|
||||
# openid_connect_1.callback_url=http://127.0.0.1:8080/auth/openid-connect/callback
|
||||
@ -477,6 +477,18 @@ In order to enable an OIDC workflow at an instance of OBP-API portal app(login f
|
||||
# openid_connect_1.endpoint.token=https://oauth2.googleapis.com/token
|
||||
# openid_connect_1.endpoint.jwks_uri=https://www.googleapis.com/oauth2/v3/certs
|
||||
# openid_connect_1.access_type_offline=false
|
||||
# openid_connect_1.button_text = Yahoo
|
||||
|
||||
## Yahoo as an identity provider
|
||||
# openid_connect_2.client_secret=685d47412efd8b74891ad711876558189793e957
|
||||
# openid_connect_2.client_id=zg0yJmk9WUEzaERzd1RtMU02JmQ9WVdrOU9FOHpTbXN5TkhNbWNHbzlNQS0tJnM9Y38uc3VtZXJzZWNyZXQmc3Y9MCZ4PWjW
|
||||
# openid_connect_2.callback_url=https://1aaac045.ngrok.io/auth/openid-connect/callback-2
|
||||
# openid_connect_2.endpoint.authorization=https://api.login.yahoo.com/oauth2/request_auth
|
||||
# openid_connect_2.endpoint.userinfo=https://api.login.yahoo.com/openid/v1/userinfo
|
||||
# openid_connect_2.endpoint.token=https://api.login.yahoo.com/oauth2/get_token
|
||||
# openid_connect_2.endpoint.jwks_uri=https://api.login.yahoo.com/openid/v1/certs
|
||||
# openid_connect_2.access_type_offline=true
|
||||
# openid_connect_2.button_text = Yahoo
|
||||
```
|
||||
Please note in the example above you MUST run OBP-API portal at the URL: http://127.0.0.1:8080
|
||||
|
||||
|
||||
@ -126,6 +126,25 @@ object JwtUtil extends MdcLoggable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Issuer Identifier for the Issuer of the response.
|
||||
* Get the value of the "iss" claim, or None if it's not available.
|
||||
*
|
||||
* @return the Issuer's value or None.
|
||||
*/
|
||||
def getAlgorithm(jwtToken: String): Option[JWSAlgorithm] = {
|
||||
try {
|
||||
val signedJWT = SignedJWT.parse(jwtToken)
|
||||
// claims extraction...
|
||||
Some(signedJWT.getHeader().getAlgorithm())
|
||||
} catch {
|
||||
case e: Exception =>
|
||||
logger.error(msg = "code.api.util.JwtUtil.getAlgorithm")
|
||||
logger.error(e)
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function validates Access Token
|
||||
* @param accessToken The access token to validate, typically submitted with a HTTP header like
|
||||
@ -186,7 +205,7 @@ object JwtUtil extends MdcLoggable {
|
||||
val iss: Issuer = new Issuer(getIssuer(idToken).getOrElse(""))
|
||||
val aud = getAudience(idToken).headOption.getOrElse("")
|
||||
val clientID: ClientID = new ClientID(aud)
|
||||
val jwsAlg: JWSAlgorithm = JWSAlgorithm.RS256
|
||||
val jwsAlg: JWSAlgorithm = getAlgorithm(idToken).getOrElse(JWSAlgorithm.RS256)
|
||||
val jwkSetURL: URL = new URL(remoteJWKSetUrl)
|
||||
|
||||
// Create validator for signed ID tokens
|
||||
|
||||
@ -64,6 +64,7 @@ object Migration extends MdcLoggable {
|
||||
bankAccountHoldersAndOwnerViewAccessInfo()
|
||||
alterTableMappedConsent()
|
||||
alterColumnChallengeAtTableMappedConsent()
|
||||
alterTableOpenIDConnectToken()
|
||||
}
|
||||
|
||||
private def dummyScript(): Boolean = {
|
||||
@ -158,6 +159,13 @@ object Migration extends MdcLoggable {
|
||||
MigrationOfMappedConsent.alterColumnChallenge(name)
|
||||
}
|
||||
}
|
||||
private def alterTableOpenIDConnectToken(): Boolean = {
|
||||
val name = nameOf(alterTableOpenIDConnectToken)
|
||||
runOnce(name) {
|
||||
MigrationOfOpnIDConnectToken.alterColumnAccessToken(name)
|
||||
MigrationOfOpnIDConnectToken.alterColumnRefreshToken(name)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
package code.api.util.migration
|
||||
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.{ZoneId, ZonedDateTime}
|
||||
|
||||
import code.api.util.APIUtil
|
||||
import code.api.util.migration.Migration.{DbFunction, saveLog}
|
||||
import code.token.OpenIDConnectToken
|
||||
import net.liftweb.mapper.{DB, Schemifier}
|
||||
import net.liftweb.util.DefaultConnectionIdentifier
|
||||
|
||||
object MigrationOfOpnIDConnectToken {
|
||||
|
||||
val oneDayAgo = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(1)
|
||||
val oneYearInFuture = ZonedDateTime.now(ZoneId.of("UTC")).plusYears(1)
|
||||
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm'Z'")
|
||||
|
||||
def alterColumnAccessToken(name: String): Boolean = {
|
||||
DbFunction.tableExists(OpenIDConnectToken, (DB.use(DefaultConnectionIdentifier){ conn => conn})) match {
|
||||
case true =>
|
||||
val startDate = System.currentTimeMillis()
|
||||
val commitId: String = APIUtil.gitCommit
|
||||
var isSuccessful = false
|
||||
|
||||
val executedSql =
|
||||
DbFunction.maybeWrite(true, Schemifier.infoF _, DB.use(DefaultConnectionIdentifier){ conn => conn}) {
|
||||
() => "ALTER TABLE openidconnecttoken ALTER COLUMN accesstoken type text;"
|
||||
}
|
||||
|
||||
val endDate = System.currentTimeMillis()
|
||||
val comment: String =
|
||||
s"""Executed SQL:
|
||||
|$executedSql
|
||||
|""".stripMargin
|
||||
isSuccessful = true
|
||||
saveLog(name, commitId, isSuccessful, startDate, endDate, comment)
|
||||
isSuccessful
|
||||
|
||||
case false =>
|
||||
val startDate = System.currentTimeMillis()
|
||||
val commitId: String = APIUtil.gitCommit
|
||||
val isSuccessful = false
|
||||
val endDate = System.currentTimeMillis()
|
||||
val comment: String =
|
||||
s"""${OpenIDConnectToken._dbTableNameLC} table does not exist""".stripMargin
|
||||
saveLog(name, commitId, isSuccessful, startDate, endDate, comment)
|
||||
isSuccessful
|
||||
}
|
||||
}
|
||||
def alterColumnRefreshToken(name: String): Boolean = {
|
||||
DbFunction.tableExists(OpenIDConnectToken, (DB.use(DefaultConnectionIdentifier){ conn => conn})) match {
|
||||
case true =>
|
||||
val startDate = System.currentTimeMillis()
|
||||
val commitId: String = APIUtil.gitCommit
|
||||
var isSuccessful = false
|
||||
|
||||
val executedSql =
|
||||
DbFunction.maybeWrite(true, Schemifier.infoF _, DB.use(DefaultConnectionIdentifier){ conn => conn}) {
|
||||
() => "ALTER TABLE openidconnecttoken ALTER COLUMN refreshtoken type text;"
|
||||
}
|
||||
|
||||
val endDate = System.currentTimeMillis()
|
||||
val comment: String =
|
||||
s"""Executed SQL:
|
||||
|$executedSql
|
||||
|""".stripMargin
|
||||
isSuccessful = true
|
||||
saveLog(name, commitId, isSuccessful, startDate, endDate, comment)
|
||||
isSuccessful
|
||||
|
||||
case false =>
|
||||
val startDate = System.currentTimeMillis()
|
||||
val commitId: String = APIUtil.gitCommit
|
||||
val isSuccessful = false
|
||||
val endDate = System.currentTimeMillis()
|
||||
val comment: String =
|
||||
s"""${OpenIDConnectToken._dbTableNameLC} table does not exist""".stripMargin
|
||||
saveLog(name, commitId, isSuccessful, startDate, endDate, comment)
|
||||
isSuccessful
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -318,6 +318,7 @@ import net.liftweb.util.Helpers._
|
||||
def getCurrentUserUsername: String = {
|
||||
getCurrentUser match {
|
||||
case Full(user) if user.provider.contains("google") => user.emailAddress
|
||||
case Full(user) if user.provider.contains("yahoo") => user.emailAddress
|
||||
case Full(user) => user.name
|
||||
case _ => "" //TODO need more error handling for different user cases
|
||||
}
|
||||
|
||||
@ -25,9 +25,9 @@ object MappedOpenIDConnectTokensProvider extends OpenIDConnectTokensProvider {
|
||||
class OpenIDConnectToken extends OpenIDConnectTokenTrait with LongKeyedMapper[OpenIDConnectToken] with IdPK with CreatedUpdated {
|
||||
|
||||
def getSingleton: OpenIDConnectToken.type = OpenIDConnectToken
|
||||
object AccessToken extends MappedString(this, 1024)
|
||||
object AccessToken extends MappedText(this)
|
||||
object IDToken extends MappedText(this)
|
||||
object RefreshToken extends MappedString(this, 1024)
|
||||
object RefreshToken extends MappedText(this)
|
||||
object Scope extends MappedString(this, 250)
|
||||
object TokenType extends MappedString(this, 250)
|
||||
object ExpiresIn extends MappedLong(this)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user