API Explorer

Authentication: Credential Checking Flow

			 |### Overview
			 |
			 |OBP supports both **local** and **external** credential checking. Local credentials are verified against the AuthUser table (bcrypt). External credentials are delegated to a core banking system or identity provider via the Connector.
			 |
			 |### Login Flow (Web Form and DirectLogin)
			 |
			 |```
			 |                         ┌─────────────────────────┐
			 |                         │      LOGIN REQUEST       │
			 |                         │   (username + password)  │
			 |                         │                          │
			 |                         │  Via: Web Form login()   │
			 |                         │   or DirectLogin header  │
			 |                         └────────────┬─────────────┘
			 |                                      │
			 |                                      ▼
			 |                         ┌─────────────────────────┐
			 |                         │  Look up AuthUser by     │
			 |                         │  username in local DB    │
			 |                         └────────────┬─────────────┘
			 |                                      │
			 |                    ┌─────────────────┼─────────────────┐
			 |                    │                 │                  │
			 |                    ▼                 ▼                  ▼
			 |              ┌──────────┐    ┌─────────────┐    ┌───────────┐
			 |              │  FOUND   │    │   FOUND     │    │ NOT FOUND │
			 |              │  Local   │    │  External   │    │           │
			 |              │ Provider │    │  Provider   │    │           │
			 |              └────┬─────┘    └──────┬──────┘    └─────┬─────┘
			 |                   │                 │                  │
			 |                   ▼                 ▼                  ▼
			 |            ┌────────────┐   ┌─────────────┐   ┌──────────────┐
			 |            │ Validated? │   │  Validated? │   │ Props:       │
			 |            │ Locked?    │   │  Locked?    │   │ connector.   │
			 |            └─────┬──────┘   └──────┬──────┘   │ user.auth    │
			 |                  │                 │          │ == true?     │
			 |           ┌──Yes─┘                 │          └──────┬───────┘
			 |           │                        │            No┌──┘Yes
			 |           ▼                        │              ▼    │
			 |   ┌───────────────┐                │         ┌──────┐  │
			 |   │ testPassword() │                │         │REJECT│  │
			 |   │ (local bcrypt  │                │         └──────┘  │
			 |   │  check)        │                │                   │
			 |   └───────┬────────┘                │                   │
			 |           │                         ▼                   ▼
			 |           │                  ┌─────────────┐   ┌──────────────────┐
			 |           │                  │ Props:      │   │                  │
			 |           │                  │ connector.  │   │  externalUser    │
			 |           │                  │ user.auth   │   │  Helper()        │
			 |           │                  │ == true?    │   │                  │
			 |           │                  └──────┬──────┘   └────────┬─────────┘
			 |           │                    No┌──┘Yes                │
			 |           │                      ▼    │                 │
			 |           │                 ┌──────┐  │                 │
			 |           │                 │REJECT│  │                 │
			 |           │                 └──────┘  │                 │
			 |           │                           ▼                 │
			 |           │              ┌──────────────────────────────┘
			 |           │              │
			 |           │              ▼
			 |           │   ╔══════════════════════════════════════════════════╗
			 |           │   ║      checkExternalUserViaConnector()            ║
			 |           │   ║                                                  ║
			 |           │   ║  Connector.checkExternalUserCredentials          ║
			 |           │   ║         (username, password)                     ║
			 |           │   ║                                                  ║
			 |           │   ║  ┌──────────────┬──────────────┬──────────────┐ ║
			 |           │   ║  │ Akka         │ StoredProc   │ LocalMapped  │ ║
			 |           │   ║  │ Connector    │ Connector    │ Connector    │ ║
			 |           │   ║  │              │              │              │ ║
			 |           │   ║  │ southSide    │ HTTP call to │ Returns      │ ║
			 |           │   ║  │ Actor msg    │ stored proc  │ Failure("")  │ ║
			 |           │   ║  │ "obp.check   │ "obp_check_  │ (N/A)       │ ║
			 |           │   ║  │  External    │  external_   │              │ ║
			 |           │   ║  │  UserCreds"  │  user_creds" │              │ ║
			 |           │   ║  └──────┬───────┴──────┬───────┴──────────────┘ ║
			 |           │   ║         │              │                         ║
			 |           │   ║         ▼              ▼                         ║
			 |           │   ║   ┌──────────────────────────┐                  ║
			 |           │   ║   │  External System /       │                  ║
			 |           │   ║   │  Core Banking Adapter    │                  ║
			 |           │   ║   │                          │                  ║
			 |           │   ║   │  Validates credentials   │                  ║
			 |           │   ║   │  Returns:                │                  ║
			 |           │   ║   │   InboundExternalUser    │                  ║
			 |           │   ║   │   - sub  (user id)       │                  ║
			 |           │   ║   │   - iss  (provider)      │                  ║
			 |           │   ║   │   - email                │                  ║
			 |           │   ║   │   - emailVerified        │                  ║
			 |           │   ║   │   - name                 │                  ║
			 |           │   ║   │   - userAuthContext       │                  ║
			 |           │   ║   └────────────┬─────────────┘                  ║
			 |           │   ╚════════════════╪═════════════════════════════════╝
			 |           │                    │
			 |           │              ┌─────┴──────┐
			 |           │              │            │
			 |           │           Success      Failure
			 |           │              │            │
			 |           │              ▼            ▼
			 |           │   ┌────────────────┐  ┌────────────┐
			 |           │   │ User exists    │  │ Increment  │
			 |           │   │ locally by     │  │ bad login  │
			 |           │   │ (sub, iss)?    │  │ attempts   │
			 |           │   └───┬────────┬───┘  │ → REJECT   │
			 |           │       │        │      └────────────┘
			 |           │     Yes        No
			 |           │       │        │
			 |           │       ▼        ▼
			 |           │   ┌───────┐ ┌──────────────────┐
			 |           │   │ Use   │ │ Create new       │
			 |           │   │ exist-│ │ AuthUser +       │
			 |           │   │ ing   │ │ ResourceUser     │
			 |           │   │ Auth  │ │  user = sub      │
			 |           │   │ User  │ │  provider = iss  │
			 |           │   │       │ │  password = UUID  │
			 |           │   │       │ │  (dummy, unused) │
			 |           │   └───┬───┘ └────────┬─────────┘
			 |           │       └──────┬───────┘
			 |           │              │
			 |     ┌─────┴──────────────┘
			 |     │
			 |     ▼
			 |┌─────────────┐      ┌──────────────┐
			 |│  SUCCESS    │      │   FAILURE    │
			 |│             │      │              │
			 |│ Reset bad   │      │ Increment    │
			 |│ login       │      │ bad login    │
			 |│ attempts    │      │ attempts     │
			 |│             │      │              │
			 |│ Establish   │      │ Lock if max  │
			 |│ session     │      │ exceeded     │
			 |│             │      │              │
			 |│ Redirect    │      │ Return error │
			 |└─────────────┘      └──────────────┘
			 |```
			 |
			 |### Decision Logic
			 |
			 |The **provider** field on the AuthUser record determines which path is taken:
			 |
			 |- **Local provider** (e.g. the OBP instance URL) → bcrypt password check via `testPassword()`
			 |- **External provider** (e.g. `google.com`) → delegated to the Connector via `checkExternalUserCredentials()`
			 |- **User not found locally** → can still succeed if `connector.user.authentication=true` is set. The system creates a new AuthUser + ResourceUser on the fly from the adapter response.
			 |
			 |The property `connector.user.authentication=true` must be set to enable external credential checking. Without it, external auth is rejected.
			 |
			 |### Verify Credentials Endpoint (POST /users/verify-credentials)
			 |
			 |In addition to the login flows above, OBP v6.0.0 provides a **credential verification endpoint** that validates credentials **without** creating a session or token.
			 |
			 |```
			 |              ┌──────────────────────────────────────────────┐
			 |              │   POST /obp/v6.0.0/users/verify-credentials │
			 |              │                                              │
			 |              │   Body: { username, password, provider }     │
			 |              │                                              │
			 |              │   → Does NOT create session/token            │
			 |              │   → Just validates and returns user info     │
			 |              │   → For external systems to verify creds     │
			 |              └────────────────────┬─────────────────────────┘
			 |                                   │
			 |                                   ▼
			 |                        ┌─────────────────────┐
			 |                        │ authenticatedAccess  │
			 |                        │ (caller must already │
			 |                        │  be logged in)       │
			 |                        └──────────┬──────────┘
			 |                                   │
			 |                                   ▼
			 |                        ┌─────────────────────┐
			 |                        │ Check role:          │
			 |                        │ isSuperAdmin?        │
			 |                        │ OR has               │
			 |                        │ canVerifyUserCreds?  │
			 |                        └──────────┬──────────┘
			 |                                   │
			 |                                   ▼
			 |              ┌────────────────────────────────────────┐
			 |              │  AuthUser.getResourceUserId             │
			 |              │     (username, password)                │
			 |              │                                        │
			 |              │  Same method used by DirectLogin and   │
			 |              │  the login flows above                  │
			 |              └──────────────────┬─────────────────────┘
			 |                                 │
			 |                (same local / external / not-found
			 |                 branching as the login flow above)
			 |                                 │
			 |                                 ▼
			 |                      ┌───────────────────┐
			 |                      │ Locked?           │──Yes──▶ 401
			 |                      └────────┬──────────┘
			 |                               │ No
			 |                               ▼
			 |                      ┌───────────────────┐
			 |                      │ Valid userId?     │──No───▶ 401
			 |                      └────────┬──────────┘
			 |                               │ Yes
			 |                               ▼
			 |                      ┌───────────────────┐
			 |                      │ Provider matches  │
			 |                      │ posted provider?  │──No───▶ 401
			 |                      │ (if non-empty)    │
			 |                      └────────┬──────────┘
			 |                               │ Yes
			 |                               ▼
			 |                      ┌───────────────────┐
			 |                      │ 200 OK            │
			 |                      │ Return UserJson   │
			 |                      │                   │
			 |                      │ NO token created  │
			 |                      │ NO session created│
			 |                      └───────────────────┘
			 |```
			 |
			 |**Key differences from the login flows:**
			 |
			 |1. **Check only** — validates credentials and returns user info, but does not create a session or token
			 |2. **Requires an already-authenticated caller** with `canVerifyUserCredentials` role (or SuperAdmin)
			 |3. **May auto-provision users** — if the local lookup fails and the external fallback via `checkExternalUserViaConnector()` succeeds, a new AuthUser and ResourceUser will be created locally (same behaviour as the web login flow)
			 |4. **Provider matching** — optionally verifies the user's provider matches what was posted (skipped if provider is empty)
			 |
			 |### Key Source Files
			 |
			 |- `AuthUser.scala` — `login()` entry point, `getResourceUserId()`, `checkExternalUserViaConnector()`
			 |- `directlogin.scala` — `getUserId()` with local-then-external fallback
			 |- `Connector.scala` — `checkExternalUserCredentials()` abstract method
			 |- `AkkaConnector_vDec2018.scala` — Akka connector implementation
			 |- `StoredProcedureConnector_vDec2019.scala` — Stored procedure connector implementation
			 |- `Http4s600.scala` — `verifyUserCredentials` endpoint definition
			 |