July 1, 2025

๐Ÿ” OAuth 2.0 Overview: Introduction to Standards Protocol Flows and Integration with Keycloak

OAuth 2.0 is the gold standard for delegated authorization. It provides multiple flows to suit different application types and trust levels. This guide dives deep into:

  • Recap the AuthN and AuthZ

  • OAuth 2.0 Flows: Client Credentials, Authorization Code, and Authorization Code with PKCE

  • Client types: Confidential and Public

  • Sequence diagrams for each flow (compatible with https://www.websequencediagram.com)

  • Keycloak configuration examples for each flow

  • curl commands to request tokens from Keycloak

  • Security concerns, best practices, and when to use what

๐Ÿ” What is Authentication and Authorization?

ConceptMeaningExample
AuthenticationVerifying who you are.Logging in with username/password, or Google login to prove your identity.
AuthorizationVerifying what you can do or access after authentication.Can this user access /admin page or update a record after logging in?

๐Ÿงญ Purpose and Use

AspectAuthenticationAuthorization
GoalProve identityControl access to resources
Happens when?First stepAfter authentication
Protocol ExamplesOpenID Connect (on top of OAuth 2)OAuth 2.0 (Authorization Framework)
Who uses the data?Login system (e.g., Keycloak)Backend/API/gateway with access policies
Typical DataUsername, password, biometricsRoles, permissions, scopes

๐Ÿ› ️ Which Protocol Does What?

Flow or ProtocolUsed ForHandles Authentication?Handles Authorization?
OAuth 2.0Delegated access❌ No✅ Yes
OpenID Connect (OIDC)Identity layer on OAuth✅ Yes (who the user is)✅ Sometimes (via scopes/claims)
SAMLEnterprise SSO✅ Yes✅ Yes
Basic Auth / Form LoginSimple login systems✅ Yes❌ No

๐Ÿ”‘ In OAuth 2.0 Context

  • Authentication: Usually handled by OIDC or a login form in the Identity Provider (IdP) like Keycloak.

  • Authorization: Managed through OAuth 2.0 scopes, roles, or resource server policies.

๐Ÿ“˜ 1. What is an OAuth Client?

An OAuth client is an application requesting access to protected resources on a user's behalf or on its own behalf.


๐Ÿ› ️ 2. Client Types: Confidential vs Public

Type Can Store Secrets? Typical Examples
Confidential Yes Server-side apps, CLIs
Public No Mobile apps, SPAs

✅ 3. Client Credentials Flow (Confidential Client)

Use Case: Service-to-service or machine-to-machine communication (no end-user).

๐Ÿงพ Sequence Diagram

title Client Credentials Flow (Confidential Client)

Client->Auth Server: POST /token\nclient_id + client_secret\ngrant_type=client_credentials
Auth Server->Client: 200 OK\naccess_token
Client->Resource Server: GET /protected-resource\nAuthorization: Bearer access_token
Resource Server->Client: 200 OK\nprotected data



๐Ÿ”ง Keycloak Setup

  1. Go to Clients → Create a new client

  2. Client ID: my-service-client

  3. Client Type: Confidential

  4. Enable Service Accounts Enabled

  5. Set credentials and copy client_id & client_secret

  6. Assign appropriate client roles under Service Account Roles

  7. Token Endpoint: https://<keycloak-host>/realms/<realm>/protocol/openid-connect/token

curl -X POST \
  https://<keycloak-host>/realms/<realm>/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=my-service-client" \
  -d "client_secret=YOUR_CLIENT_SECRET"

๐Ÿ™‹‍♂️ 4. Authorization Code Flow (Confidential Client)

Use Case: Web applications with backend able to keep secrets. Requires user login.

๐Ÿงพ Sequence Diagram

title Authorization Code Flow (Confidential Client)

Client->User: Redirect to Auth Server login
User->Auth Server: Logs in, grants consent Auth Server->Client: Redirect with code Client->Auth Server: POST /token\ncode + client_id + client_secret Auth Server->Client: 200 OK\naccess_token + refresh_token Client->Resource Server: GET /protected-resource\nAuthorization: Bearer access_token Resource Server->Client: 200 OK\nprotected data


๐Ÿ”ง Keycloak Setup

  1. Go to Clients → Create a new client

  2. Client ID: my-web-client

  3. Client Type: Confidential

  4. Root URL: https://your-app.com

  5. Valid Redirect URIs: https://your-app.com/callback

  6. Enable Standard Flow Enabled

  7. Note the token endpoint: https://<keycloak-host>/realms/<realm>/protocol/openid-connect/token

curl -X POST \
  https://<keycloak-host>/realms/<realm>/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "client_id=my-web-client" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "code=AUTH_CODE_FROM_CALLBACK" \
  -d "redirect_uri=https://your-app.com/callback"

๐Ÿ“ฑ 5. Authorization Code Flow with PKCE (Public Client)

Use Case: Mobile apps or SPAs where secrets cannot be stored securely.

๐Ÿงพ Sequence Diagram

title Authorization Code Flow with PKCE (Public Client)

Client->Auth Server: Redirect with\ncode_challenge (PKCE)
User->Auth Server: Logs in, grants consent
Auth Server->Client: Redirect with code
Client->Auth Server: POST /token\ncode + code_verifier (PKCE)
Auth Server->Client: 200 OK\naccess_token
Client->Resource Server: GET /protected-resource\nAuthorization: Bearer access_token
Resource Server->Client: 200 OK\nprotected data



๐Ÿ”ง Keycloak Setup

  1. Go to Clients → Create a new client

  2. Client ID: my-spa-client

  3. Client Type: Public

  4. Enable Standard Flow Enabled

  5. Set Valid Redirect URIs (e.g. http://localhost:3000/*)

  6. Enable PKCE (enabled by default from Keycloak 18+)

  7. Do not set client secret (public clients should not use one)

curl -X POST \
  https://<keycloak-host>/realms/<realm>/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "client_id=my-spa-client" \
  -d "code=AUTH_CODE_FROM_CALLBACK" \
  -d "code_verifier=YOUR_CODE_VERIFIER" \
  -d "redirect_uri=http://localhost:3000/callback"

๐Ÿ›ก️ 6. Security Considerations

Risk Applies To Mitigation
Token theft All flows Use HTTPS, secure storage
Secret leakage Confidential Store secrets in vaults, env vars
Replay attacks Public clients Use PKCE with code_verifier
Authorization code leakage All code flows Use state param + PKCE
Refresh token misuse All code flows Issue only to confidential clients

๐Ÿ† 7. Which Flow to Use When?

Flow Client Type User Involved Use Case
Client Credentials Confidential No M2M, background jobs, microservices
Authorization Code Confidential Yes Web apps with secure backend
Auth Code + PKCE Public Yes SPAs, mobile apps

๐Ÿ“„ 8. Summary Table

Flow Requires Secret Safe for Public Refresh Token PKCE Required
Client Credentials Yes No No No
Authorization Code Yes No Yes No
Auth Code + PKCE No Yes Sometimes Yes

๐ŸŒŸ 9. Best Practices

  • Always use PKCE for mobile/web public clients

  • Use short-lived access tokens and rotating refresh tokens

  • Validate state and nonce to prevent CSRF and replay

  • Use scopes to enforce least privilege


๐Ÿš€ 10. Tools to Visualize Sequence Diagrams

All diagrams here are compatible with https://www.websequencediagram.com. Paste any of them to view and customize.


๐Ÿ“ Final Thoughts

Choosing the right OAuth flow depends on:

  • Whether you're authenticating a user or a service

  • Whether the client is trusted to hold secrets

  • Whether the platform supports secure storage

Use this guide as a blueprint to implement secure OAuth 2.0 integrations confidently using Keycloak as your Identity Provider.

June 30, 2025

๐Ÿ”️ Finding a Peak Element in an Array — Efficient Solutions in Java (with Java 21 Best Practices)

๐Ÿ“Œ Problem Statement

You are given an integer array nums. Your task is to find a peak element and return its index.

A peak element is one that is:

  • strictly greater than its neighbors.

  • i.e., nums[i - 1] < nums[i] > nums[i + 1].

Special Notes:

  • You only need to return any one peak — not all.

  • The array may have multiple peaks.

  • Assume nums[-1] and nums[n] are -∞ (imaginary values outside the array).


๐Ÿง  Intuition — What Is the Question Really Asking?

Imagine you're walking along a mountain trail, and someone asks:

“Can you find a point where you're standing on a hilltop, higher than both the person behind you and ahead of you?”

You don’t need the highest mountain, just any place where you're on top compared to your neighbors.

Why is this interesting?

Because instead of checking every point on the trail, you can cleverly skip sections using the idea that:

  • If you're going uphill, a peak must lie ahead.

  • If you're going downhill, a peak must lie behind or at your current position.

This observation is perfect for binary search — we can reduce our search space by half each time.


๐Ÿงช Example

Given:

int[] nums = {1, 2, 3, 1};
  • At index 2, nums[2] = 3, and 3 > 2 and 3 > 1 → so index 2 is a peak.


๐Ÿšถ‍♂️ Approach 1: Brute Force (Linear Scan)

Go element by element and check if it's greater than its neighbors.

public static int findPeakLinear(int[] nums) {
    for (int i = 0; i < nums.length; i++) {
        boolean leftOk = (i == 0 || nums[i] > nums[i - 1]);
        boolean rightOk = (i == nums.length - 1 || nums[i] > nums[i + 1]);
        if (leftOk && rightOk) return i;
    }
    return -1; // fallback
}

✅ Pros:

  • Very easy to implement

❌ Cons:

  • Time complexity: O(n)

  • Not efficient for large arrays


⚡ Approach 2: Binary Search (Optimal and Recommended)

Use the fact that a peak exists if the slope changes from rising to falling. If nums[mid] < nums[mid + 1], move right. Else, move left.

Java 21 Version

public class PeakFinder {

    public static int findPeakElement(int[] nums) {
        if (nums == null || nums.length == 0)
            throw new IllegalArgumentException("Array must not be null or empty");

        int left = 0, right = nums.length - 1;

        while (left < right) {
            int mid = Math.addExact(left, (right - left) / 2);

            if (nums[mid] < nums[mid + 1]) {
                left = mid + 1; // peak is to the right
            } else {
                right = mid; // peak is to the left or at mid
            }
        }

        return left;
    }
}

⏱️ Time: O(log n)

๐Ÿ“ฆ Space: O(1)

✅ Pros:

  • Very efficient

  • Guarantees a peak due to the problem’s conditions


๐Ÿงฉ Approach 3: Recursive Divide and Conquer

Same logic as binary search, but using recursion:

public class PeakFinder {

    public static int findPeakRecursive(int[] nums) {
        return search(nums, 0, nums.length - 1);
    }

    private static int search(int[] nums, int left, int right) {
        if (left == right) return left;

        int mid = left + (right - left) / 2;

        if (nums[mid] < nums[mid + 1]) {
            return search(nums, mid + 1, right);
        } else {
            return search(nums, left, mid);
        }
    }
}

๐Ÿ“ˆ Real-World Analogy (Peak Hiker)

Think of yourself as a hiker on a trail:

  • When the path is going up, you know a peak is ahead.

  • When the path goes down, the peak was behind or at your feet.

  • If you're already on a peak, stop walking.

Binary search lets you skip large parts of the trail because you're always choosing the direction that guarantees a peak exists.


๐Ÿง  Why Binary Search Works Here

Even though the array is not sorted, you can still apply binary search because:

  • There is always at least one peak.

  • At each step, you can eliminate half the array based on the comparison of nums[mid] and nums[mid+1].


✅ Summary Table

Approach Time Complexity Space Complexity Best Use Case
Linear Scan O(n) O(1) Small inputs or quick demo
Binary Search O(log n) O(1) Optimal, all scenarios ✅
Recursive O(log n) O(log n) When recursion is preferred

๐Ÿ’ก Interview Tip

Even if the array isn't sorted, binary search can still be applied in problems where the structure allows elimination of search space — and this is a perfect example.


๐Ÿ› ️ Extras for Practice

  • Modify to find all peak elements

  • Apply a similar approach for a 2D matrix peak problem

  • Implement in a functional style using Java Streams (advanced)


Would you like this content:

  • Exported as HTML for Blogger?

  • Converted to Markdown for Dev.to or GitHub Pages?

  • Embedded with code playground for interactive testing?

Let me know — I can format it to suit your blog setup!