Saravanan's Corner: Blackberry Dev

Saturday, 9 August 2025

Thread - tricky questions

 // Online Java Compiler

// Use this editor to write, compile and run your Java code online

import java.util.concurrent.*;


class Main {

    

    public static void main(String[] args) {

        

        CountDownLatch count = new CountDownLatch(3);

        

        new Thread(()->{

            System.out.println("Hi there...1");

            try{

               Thread.sleep(1000);

               count.countDown();

            } catch(InterruptedException e){

                

            }

            System.out.println("Complete...1");

        }).start();

        

        new Thread(()->{

            System.out.println("Hi there...2");

            try{

               Thread.sleep(1000);

               count.countDown();

            } catch(InterruptedException e){

                

            }

            System.out.println("Complete...2");

        }).start();

        

        new Thread(()->{

            System.out.println("Hi there...3");

            try{

               Thread.sleep(1000);

               count.await();

            } catch(InterruptedException e){

                

            }

            System.out.println("Complete...3");

        }).start();

        

        new Thread(()->{

            System.out.println("Hi there...4");

            try{

               Thread.sleep(1000);

               count.countDown();

            } catch(InterruptedException e){}

            System.out.println("Complete...4");

        }).start();

        

         System.out.println("........Using Completable future...");

         

         CompletableFuture<Void> task1 = CompletableFuture.runAsync(

         ()-> {

             System.out.println("task1 CompletableFuture started");

             try{

               Thread.sleep(1000);

               count.countDown();

            } catch(InterruptedException e){}

            System.out.println("CompletableFuture Complete...1");

         }

         

         );

             

        CompletableFuture<Void> task2 = CompletableFuture.runAsync(

         ()-> {

             System.out.println("task2 CompletableFuture started");

             try{

               Thread.sleep(1000);

               count.countDown();

            } catch(InterruptedException e){}

            System.out.println("CompletableFuture Complete...2");

         }

         );

        CompletableFuture<Void> task4 = CompletableFuture.runAsync(

         ()-> {

             System.out.println("task4 CompletableFuture started");

             try{

               Thread.sleep(1000);

               count.countDown();

            } catch(InterruptedException e){}

            System.out.println("CompletableFuture Complete...4");

         });

        CompletableFuture<Void> task3 = CompletableFuture.allOf(task1, task2, task4).thenRun(

             ()-> {

                 System.out.println("task3 CompletableFuture started");

                  try{

               Thread.sleep(1000);

               count.countDown();

            } catch(InterruptedException e){}

            System.out.println("CompletableFuture Complete...3");

                 

             }

        );

    }

}

Friday, 1 August 2025

The Spring Security JWT token authentication flow

 The Spring Security JWT token authentication flow involves several steps, typically illustrated through two main phases: Login/Token Generation and Resource Access/Token Validation.

1. Login/Token Generation Flow:
Client Sends Credentials:
The client (e.g., web browser, mobile app) sends user credentials (username and password) to the Spring Boot application's authentication endpoint.
Authentication Controller:
The application's authentication controller receives these credentials.
AuthenticationManager:
The controller delegates the authentication process to the AuthenticationManager.
AuthenticationProvider:
The AuthenticationManager uses an AuthenticationProvider (often integrated with UserDetailsService) to validate the credentials against a user store (e.g., database).
Successful Authentication:
If credentials are valid, the AuthenticationProvider returns an Authentication object.
JWT Generation:
A JWT utility class or service generates a new JWT containing user details (claims) and signs it using a secret key.
Token Sent to Client:
The generated JWT is returned to the client in the authentication response.
2. Resource Access/Token Validation Flow:
Client Sends JWT:
For subsequent requests to protected resources, the client includes the obtained JWT, typically in the Authorization header as a "Bearer" token.
Spring Security Filter Chain:
The request enters the Spring Security filter chain.
JwtAuthenticationFilter:
A custom JwtAuthenticationFilter (or similar filter) intercepts the request early in the chain.
Token Extraction and Validation:
This filter extracts the JWT from the header and validates it using the secret key (e.g., signature verification, expiration check, claim validation).
User Details Loading:
If the token is valid, the filter extracts user details (e.g., username) from the token's claims and loads the full UserDetails object, often via a UserDetailsService.
SecurityContextHolder:
An Authentication object is created with the loaded UserDetails and set in the SecurityContextHolder, making the user authenticated for the current request.
Authorization:
Subsequent filters or controllers in the chain can then perform authorization checks based on the authenticated user's roles or authorities.
Access Protected Resource:
If authorization is successful, the request proceeds to the intended protected resource.
Token Invalid/Missing:
If the token is invalid, missing, or expired, the JwtAuthenticationFilter or a subsequent filter will reject the request, typically returning an unauthorized (401) or forbidden (403) status.