Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ OBP_API_URL=http://localhost:8080
# Set to 'true' to skip automatic client creation on startup
OIDC_SKIP_CLIENT_BOOTSTRAP=false

# ----------------------------------------------------------------------------
# Dynamic Client Registration
# ----------------------------------------------------------------------------
# Set to 'true' to enable dynamic client registration endpoint
# WARNING: This can pose security risks if not properly managed!
# Needs to be enabled for OBP-OIDC to work with MCP servers.
ENABLE_DYNAMIC_CLIENT_REGISTRATION=false

# ----------------------------------------------------------------------------
# Database Configuration (Read-Only User)
# ----------------------------------------------------------------------------
Expand Down
53 changes: 53 additions & 0 deletions obp-oidc-generated-config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# OBP-OIDC Generated Configuration
# Generated at: 2025-08-29T13:47:28.569688Z
# Copy the sections you need to your project configuration files

# ============================================================================
# 1. OBP-API Configuration (Props file)
# ============================================================================
# Add to your OBP-API props file
openid_connect.scope=openid email profile

# OBP-API OIDC Provider Settings
openid_connect.endpoint=http://localhost:9000/obp-oidc/.well-known/openid_configuration
oauth2.client_id=obp-api-client
oauth2.client_secret=iQZPiGjZ4ZgKP63sYJGl17lkIpWvihX4f5_iKrVXYfI
oauth2.callback_url=http://localhost:8080/auth/openid-connect/callback

# ============================================================================
# 2. OBP-Portal Configuration (.env file)
# ============================================================================
# Add to your OBP-Portal .env file
OBP_OAUTH_CLIENT_ID=obp-portal-client
OBP_OAUTH_CLIENT_SECRET=2sev_vjY94fHeCstao2PcOh0K5tFFPs7kEOFQhmoME4
OBP_OAUTH_WELL_KNOWN_URL=http://localhost:9000/obp-oidc/.well-known/openid-configuration
APP_CALLBACK_URL=http://localhost:5174/login/obp/callback
VITE_API_URL=http://localhost:8080
VITE_OIDC_ISSUER=http://localhost:9000/obp-oidc
VITE_CLIENT_ID=obp-portal-client

# ============================================================================
# 3. API-Explorer-II Configuration (environment variables)
# ============================================================================
# Add to your API-Explorer-II environment
export REACT_APP_OAUTH_CLIENT_ID=obp-explorer-ii-client
export REACT_APP_OAUTH_CLIENT_SECRET=EHtey9xcSBaU0SGUzkSS8orjXuM3a7FqD987FzTHxio
export REACT_APP_OAUTH_AUTHORIZATION_URL=http://localhost:9000/obp-oidc/auth
export REACT_APP_OAUTH_TOKEN_URL=http://localhost:9000/obp-oidc/token
export REACT_APP_OAUTH_REDIRECT_URI=http://localhost:3001/callback

# ============================================================================
# 4. Opey-II Configuration (environment variables)
# ============================================================================
# Add to your Opey-II environment
export VUE_APP_OAUTH_CLIENT_ID=obp-opey-ii-client
export VUE_APP_OAUTH_CLIENT_SECRET=5rZntd0jUp_-3j--BHSGfj6HmzyILiYuZaaM7UGfUEU
export VUE_APP_OAUTH_AUTHORIZATION_URL=http://localhost:9000/obp-oidc/auth
export VUE_APP_OAUTH_TOKEN_URL=http://localhost:9000/obp-oidc/token
export VUE_APP_OAUTH_REDIRECT_URI=http://localhost:3002/callback

# ============================================================================
# Database Client Information
# ============================================================================
# Client IDs and secrets are also stored in your v_oidc_admin_clients table
# Use these for reference or manual configuration
8 changes: 3 additions & 5 deletions src/main/scala/com/tesobe/oidc/auth/DatabaseAuthService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1284,11 +1284,9 @@ object AdminDatabaseClient {
description = Some(s"OIDC client for ${client.client_name}"),
developeremail = Some("admin@tesobe.com"), // Default email
sub = Some(client.client_name), // Use client name as sub
consumerid = Some(
client.consumer_id
), // Use consumer_id for internal tracking (primary key)
createdat = Some(Instant.now()), // Set creation timestamp
updatedat = Some(Instant.now()), // Set update timestamp
consumerid = Some(client.consumer_id),
createdat = None, // Let database set this
updatedat = None, // Let database set this
secret = client.client_secret,
azp = Some(client.client_id),
aud = Some("obp-api"),
Expand Down
7 changes: 5 additions & 2 deletions src/main/scala/com/tesobe/oidc/config/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ case class OidcConfig(
"https://static.openbankproject.com/images/OBP/OBP_Horizontal_2025.png"
),
logoAltText: String = "Open Bank Project",
forgotPasswordUrl: Option[String] = None
forgotPasswordUrl: Option[String] = None,
enableDynamicClientRegistration: Boolean = false
)

object Config {
Expand Down Expand Up @@ -118,7 +119,9 @@ object Config {
)
),
logoAltText = sys.env.getOrElse("LOGO_ALT_TEXT", "Open Bank Project"),
forgotPasswordUrl = sys.env.get("FORGOT_PASSWORD_URL")
forgotPasswordUrl = sys.env.get("FORGOT_PASSWORD_URL"),
enableDynamicClientRegistration =
sys.env.getOrElse("ENABLE_DYNAMIC_CLIENT_REGISTRATION", "false").toBoolean
)
}
}
3 changes: 2 additions & 1 deletion src/main/scala/com/tesobe/oidc/endpoints/AuthEndpoint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -622,8 +622,9 @@ class AuthEndpoint(
code: String,
state: Option[String]
): IO[Response[IO]] = {
val stateParam = state.map(s => s"&state=$s").getOrElse("")
val stateParam = state.map(s => s"&state=${java.net.URLEncoder.encode(s, "UTF-8")}").getOrElse("") // Code URL-encoding
val location = s"$redirectUri?code=$code$stateParam"
IO(println(s"🔄 Redirecting with code to: $location")) *>
SeeOther(Location(Uri.unsafeFromString(location)))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class DiscoveryEndpoint(config: OidcConfig) {
userinfo_endpoint = s"${config.issuer}/userinfo",
jwks_uri = s"${config.issuer}/jwks",
revocation_endpoint = s"${config.issuer}/revoke",
registration_endpoint = if (config.enableDynamicClientRegistration) Some(s"${config.issuer}/connect/register") else None,
response_types_supported = List("code"),
subject_types_supported = List("public"),
id_token_signing_alg_values_supported = List("RS256"),
Expand All @@ -69,6 +70,7 @@ class DiscoveryEndpoint(config: OidcConfig) {
userinfo_endpoint = s"${config.issuer}/userinfo",
jwks_uri = s"${config.issuer}/jwks",
revocation_endpoint = s"${config.issuer}/revoke",
registration_endpoint = if (config.enableDynamicClientRegistration) Some(s"${config.issuer}/connect/register") else None,
response_types_supported = List("code"),
subject_types_supported = List("public"),
id_token_signing_alg_values_supported = List("RS256"),
Expand Down
Loading