Monday, December 12, 2022

Spring Boot 3 : JWT with SecurityFilterChain, AuthorizeHttpRequests, RequestMatchers

pom.xml
 <?xml version="1.0" encoding="UTF-8"?>  
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">  
      <modelVersion>4.0.0</modelVersion>  
      <parent>  
           <groupId>org.springframework.boot</groupId>  
           <artifactId>spring-boot-starter-parent</artifactId>  
           <version>3.0.0</version>  
           <relativePath/> <!-- lookup parent from repository -->  
      </parent>  
      <groupId>com.javawithlwl</groupId>  
      <artifactId>spring-security</artifactId>  
      <version>0.0.1-SNAPSHOT</version>  
      <name>spring-security</name>  
      <description>Spring Security with Spring Boot</description>  
      <properties>  
           <java.version>19</java.version>  
           <jjwt.version>0.9.1</jjwt.version>  
           <jaxb.version>2.3.1</jaxb.version>  
      </properties>  
      <dependencies>  
           <dependency>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-starter-security</artifactId>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-starter-web</artifactId>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-devtools</artifactId>  
                <scope>runtime</scope>  
                <optional>true</optional>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-configuration-processor</artifactId>  
                <optional>true</optional>  
           </dependency>  
           <dependency>  
                <groupId>org.projectlombok</groupId>  
                <artifactId>lombok</artifactId>  
                <optional>true</optional>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-starter-test</artifactId>  
                <scope>test</scope>  
           </dependency>  
           <dependency>  
                <groupId>org.springframework.security</groupId>  
                <artifactId>spring-security-test</artifactId>  
                <scope>test</scope>  
           </dependency>  
           <dependency>  
                <groupId>io.jsonwebtoken</groupId>  
                <artifactId>jjwt</artifactId>  
                <version>${jjwt.version}</version>  
           </dependency>  
           <dependency>  
                <groupId>javax.xml.bind</groupId>  
                <artifactId>jaxb-api</artifactId>  
                <version>${jaxb.version}</version>  
           </dependency>  
      </dependencies>  
      <build>  
           <plugins>  
                <plugin>  
                     <groupId>org.springframework.boot</groupId>  
                     <artifactId>spring-boot-maven-plugin</artifactId>  
                     <configuration>  
                          <excludes>  
                               <exclude>  
                                    <groupId>org.projectlombok</groupId>  
                                    <artifactId>lombok</artifactId>  
                               </exclude>  
                          </excludes>  
                     </configuration>  
                </plugin>  
           </plugins>  
      </build>  
 </project>  
Spring Security Configuration:
 package com.javawithlwl.springsecurity.config;  
 import lombok.RequiredArgsConstructor;  
 import org.springframework.context.annotation.Bean;  
 import org.springframework.context.annotation.Configuration;  
 import org.springframework.security.authentication.AuthenticationManager;  
 import org.springframework.security.authentication.ProviderManager;  
 import org.springframework.security.authentication.dao.DaoAuthenticationProvider;  
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
 import org.springframework.security.config.http.SessionCreationPolicy;  
 import org.springframework.security.core.userdetails.UserDetailsService;  
 import org.springframework.security.crypto.password.PasswordEncoder;  
 import org.springframework.security.web.SecurityFilterChain;  
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;  
 @Configuration  
 @EnableWebSecurity  
 @RequiredArgsConstructor  
 public class AppSecurityConfiguration {  
  private final PasswordEncoder passwordEncoder;  
  private final JwtRequestFilter jwtRequestFilter;  
  @Bean  
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {  
   return http  
     .csrf(csrf -> csrf.disable())  
     .authorizeHttpRequests(auth -> {  
      auth.requestMatchers("/api/auth/**").permitAll();  
      auth.anyRequest().authenticated();  
     })  
     .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))  
     .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)  
     .build();  
  }  
  @Bean  
  public AuthenticationManager authenticationManager(UserDetailsService userDetailsService) {  
   var authProvider = new DaoAuthenticationProvider();  
   authProvider.setUserDetailsService(userDetailsService);  
   authProvider.setPasswordEncoder(passwordEncoder);  
   return new ProviderManager(authProvider);  
  }  
 }  
App Configuration:
 package com.javawithlwl.springsecurity.config;  
 import org.springframework.context.annotation.Bean;  
 import org.springframework.context.annotation.Configuration;  
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;  
 import org.springframework.security.crypto.password.PasswordEncoder;  
 @Configuration  
 public class AppBeanConfiguration {  
   @Bean  
   public PasswordEncoder passwordEncoder(){  
    return new BCryptPasswordEncoder();  
   }  
 }  
JWT Request Filter:
 package com.javawithlwl.springsecurity.config;  
 import jakarta.servlet.FilterChain;  
 import jakarta.servlet.ServletException;  
 import jakarta.servlet.http.HttpServletRequest;  
 import jakarta.servlet.http.HttpServletResponse;  
 import lombok.RequiredArgsConstructor;  
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;  
 import org.springframework.security.core.context.SecurityContextHolder;  
 import org.springframework.security.core.userdetails.UserDetails;  
 import org.springframework.security.core.userdetails.UserDetailsService;  
 import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;  
 import org.springframework.stereotype.Component;  
 import org.springframework.web.filter.OncePerRequestFilter;  
 import java.io.IOException;  
 @Component  
 @RequiredArgsConstructor  
 public class JwtRequestFilter extends OncePerRequestFilter {  
  private final JwtUtil jwtUtil;  
  private final UserDetailsService userService;  
  @Override  
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {  
   final String authHeader = request.getHeader("Authorization");  
   String username = null;  
   String jwt = null;  
   if (authHeader != null && authHeader.startsWith("Bearer")) {  
    jwt = authHeader.substring(7);  
    username = jwtUtil.extractUsername(jwt);  
   }  
   if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {  
    UserDetails userDetails = this.userService.loadUserByUsername(username);  
    if(jwtUtil.validateToken(jwt,userDetails)){  
     UsernamePasswordAuthenticationToken authToken=new UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());  
     authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));  
     SecurityContextHolder.getContext().setAuthentication(authToken);  
    }  
   }  
   filterChain.doFilter(request,response);  
  }  
 }  
JWT Util:
 package com.javawithlwl.springsecurity.config;  
 import io.jsonwebtoken.Claims;  
 import io.jsonwebtoken.Jwts;  
 import io.jsonwebtoken.SignatureAlgorithm;  
 import org.springframework.beans.factory.annotation.Value;  
 import org.springframework.security.core.userdetails.UserDetails;  
 import org.springframework.stereotype.Component;  
 import java.util.Date;  
 import java.util.HashMap;  
 import java.util.Map;  
 import java.util.function.Function;  
 @Component  
 public class JwtUtil {  
   @Value("${jwt.secret.key:app_secret}")  
   private String SECRET_KEY;  
   public String extractUsername(String token) {  
     return extractClaim(token, Claims::getSubject);  
   }  
   public Date extractExpiration(String token) {  
     return extractClaim(token, Claims::getExpiration);  
   }  
   public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {  
     final Claims claims = extractAllClaims(token);  
     return claimsResolver.apply(claims);  
   }  
   private Claims extractAllClaims(String token) {  
     return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();  
   }  
   private Boolean isTokenExpired(String token) {  
     return extractExpiration(token).before(new Date());  
   }  
   public String generateToken(UserDetails userDetails) {  
     Map<String, Object> claims = new HashMap<>();  
     return createToken(claims, userDetails.getUsername());  
   }  
   private String createToken(Map<String, Object> claims, String subject) {  
     return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))  
         .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))  
         .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();  
   }  
   public Boolean validateToken(String token, UserDetails userDetails) {  
     final String username = extractUsername(token);  
     return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));  
   }  
 }  
Auth Controller:
 package com.javawithlwl.springsecurity.controller;  
 import com.javawithlwl.springsecurity.config.JwtUtil;  
 import com.javawithlwl.springsecurity.model.LoginRequest;  
 import com.javawithlwl.springsecurity.model.LoginResponse;  
 import lombok.RequiredArgsConstructor;  
 import org.springframework.http.ResponseEntity;  
 import org.springframework.security.authentication.AuthenticationManager;  
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;  
 import org.springframework.security.core.userdetails.UserDetails;  
 import org.springframework.security.core.userdetails.UserDetailsService;  
 import org.springframework.web.bind.annotation.PostMapping;  
 import org.springframework.web.bind.annotation.RequestBody;  
 import org.springframework.web.bind.annotation.RequestMapping;  
 import org.springframework.web.bind.annotation.RestController;  
 @RestController  
 @RequestMapping("/api/auth")  
 @RequiredArgsConstructor  
 public class AuthController {  
    private final AuthenticationManager authenticationManager;  
    private final UserDetailsService userDetailsService;  
    private final JwtUtil jwtUtil;  
    @PostMapping("/login")  
    public ResponseEntity<LoginResponse> login(@RequestBody LoginRequest loginRequest){  
       authenticationManager.authenticate(  
         new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword())  
       );  
     UserDetails userDetails = userDetailsService.loadUserByUsername(loginRequest.getUsername());  
     String jwtToken=jwtUtil.generateToken(userDetails);  
     return ResponseEntity.ok(new LoginResponse(jwtToken));  
    }  
 }  
Greeting Controller:
 package com.javawithlwl.springsecurity.controller;  
 import org.springframework.http.ResponseEntity;  
 import org.springframework.web.bind.annotation.GetMapping;  
 import org.springframework.web.bind.annotation.RequestMapping;  
 import org.springframework.web.bind.annotation.RestController;  
 import java.security.Principal;  
 @RestController  
 @RequestMapping("/api/v1/")  
 public class GreetingController {  
    @GetMapping("/greet")  
    public ResponseEntity<String> greet(Principal principal){  
     return ResponseEntity.ok(String.format("Hi %s, Welcome to Spring Boot World",principal.getName()));  
    }  
 }  
Login Request:
 package com.javawithlwl.springsecurity.model;  
 import lombok.Data;  
 @Data  
 public class LoginRequest {  
  private String username;  
  private String password;  
 }  
Login Response:
 package com.javawithlwl.springsecurity.model;  
 import lombok.AllArgsConstructor;  
 import lombok.Data;  
 @Data  
 @AllArgsConstructor  
 public class LoginResponse {  
   private String jwt;  
 }  
UserDetails Service:
 package com.javawithlwl.springsecurity.service;  
 import jakarta.annotation.PostConstruct;  
 import lombok.RequiredArgsConstructor;  
 import org.springframework.security.core.userdetails.User;  
 import org.springframework.security.core.userdetails.UserDetails;  
 import org.springframework.security.core.userdetails.UserDetailsService;  
 import org.springframework.security.core.userdetails.UsernameNotFoundException;  
 import org.springframework.security.crypto.password.PasswordEncoder;  
 import org.springframework.stereotype.Service;  
 import java.util.ArrayList;  
 import java.util.List;  
 @Service  
 @RequiredArgsConstructor  
 public class AppUserDetailsService implements UserDetailsService {  
  private final PasswordEncoder passwordEncoder;  
  private List<UserDetails> userDetails;  
  @PostConstruct  
  public void init() {  
   userDetails = new ArrayList<>(List.of(  
     User.withUsername("user")  
       .password(passwordEncoder.encode("user@123")).authorities("ROLE_USER").build(),  
     User.withUsername("admin")  
       .password(passwordEncoder.encode("admin@123")).authorities("ROLE_ADMIN").build()  
   ));  
  }  
  @Override  
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {  
   return userDetails.stream()  
     .filter(user -> user.getUsername().equals(username))  
     .findFirst()  
     .orElseThrow(() -> new UsernameNotFoundException("User not found with given username"));  
  }  
 }  
Main Class:
 package com.javawithlwl.springsecurity;  
 import org.springframework.boot.SpringApplication;  
 import org.springframework.boot.autoconfigure.SpringBootApplication;  
 @SpringBootApplication  
 public class SpringSecurityApplication {  
      public static void main(String[] args) {  
           SpringApplication.run(SpringSecurityApplication.class, args);  
      }  
 }  

Monday, December 5, 2022

Expression Evaluating - Using Java Stack

import java.util.List;
import java.util.Stack;

public class EvaluatingExpression {

  public static void main(String[] args) {
    System.out.println(evaluateExp("2+2"));
    System.out.println(evaluateExp("2 * ( 4 * 5 + 1 )"));
  }

  public static int evaluateExp(String expression) {
    char[] tokens = expression.toCharArray();
    Stack<Integer> values = new Stack<Integer>();
    Stack<Character> operators = new Stack<Character>();
    for (int i = 0; i < tokens.length; i++) {
      if (tokens[i] == ' ') {
        continue;
      }
      if (tokens[i] >= '0' && tokens[i] <= '9') {
        StringBuilder sb = new StringBuilder();
        while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9') {
          sb.append(tokens[i++]);
        }
        i--;
        values.push(Integer.parseInt(sb.toString()));
      } else if (tokens[i] == '(') {
        operators.push(tokens[i]);
      } else if (tokens[i] == ')') {
        while (operators.peek() != '(') {
          values.push(applyOperation(operators.pop(), values.pop(), values.pop()));
        }
        operators.pop();
      } else if (isOperator(tokens[i])) {
        while (!operators.isEmpty() && hasPrecedence(tokens[i], operators.peek())) {
          values.push(applyOperation(operators.pop(), values.pop(), values.pop()));
        }
        operators.push(tokens[i]);
      }
    }
    while (!operators.isEmpty()) {
      values.push(applyOperation(operators.pop(), values.pop(), values.pop()));
    }
    return values.pop();

  }

  private static boolean hasPrecedence(char op1, char op2) {
    if (op2 == '(' || op1 == ')') {
      return false;
    }
    if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) {
      return false;
    }
    return true;
  }

  private static boolean isOperator(char ch) {
    return List.of('+', '*', '-', '/').contains(ch);
  }

  private static Integer applyOperation(Character ope, Integer a, Integer b) {
    return switch (ope) {
      case '+' -> a + b;
      case '-' -> a - b;
      case '*' -> a * b;
      case '/' -> {
        if (b == 0) throw new IllegalArgumentException("Unsupported exception");
        yield a / b;
      }
      default -> throw new IllegalArgumentException("Unknown operator");
    };
  }
}

Saturday, April 24, 2021

Interview Questions - Java

Java Interview Questions

    1. What is OOP?

      Object Oriented Programming is programming paradigm, that works on the following principals:
      • Abstraction
      • Inheritance
      • Polymorphism
      • Encapsulation
    2. What is Abstraction?

      Abstraction is the process of hiding certain details and showing only essential information to the user.
    3. What is Polymorphism?

      Polymorphism is a concept by which we can perform a single action in different ways. ... So polymorphism means many forms.
    4. What is Inheritance?

      Inheritance is a mechanism in which one object acquires all the properties and behaviors of a parent object.
    5. What is immutable Object and how to create a immutable class?

    1. What is JDK,JRE JVM?

    2. Difference between prasing and type casting?

    3. What is constructor? difference between constructor and method?

    4. What are access specifiers in java ?

    5. Write a program to check given string is Anagram or not?

    1. What is Functional interface?

    2. Abstract class Vs Interface

    3. Overloading Vs Overriding

    4. What is marker interface?

    5. Write a program to delete duplicate elements from the array and display then ascending order

    1. ArrayList Vs LinkedList

    2. HashMap Vs HashTable

    3. HashMap vs ConcurrentHashMap

    4. How HashMap works internally?

    5. Write a program to implement custom hashmap

    1. Callable Vs Runnable

    2. Synchronized block vs method

    3. What are the different ways to create thered in java?

    4. How to run multiple threads simltaniously

    5. Write a program to create singleton class

    1. What is design patterns?

    2. finally Vs finalize

    3. What are the SOLID principals?

    4. What is the default capacity of LinkedList, HashMap ?

    5. Write a program for builder and factory patterns

    1. What is Streams?

    2. Inner classes Vs Lambdas

    3. What is difference between stream vs parallel stream?

    4. Future vs CompletableFuture

    5. Write a program to convert list of string to map where key is string and length of the string is value using streams

    1. Where do you volatile keyword?

    2. volatile vs transient

    3. How to store custom object as key in HashMap?

    4. What is exception? What are different ways to create custom exception

    5. Write a program to create custom exception class?

    1. What is serialaization?

    2. What is serial version id?

    3. this Vs Super in java?

    4. What are different ways to create object?

    5. Write a program to create custom annotation?

    1. How garbage collectors work in JVM?

    2. What is major GC and minor GC?

    3. What is class loader?

    4. How to increase memeory size while running java applicaation?

    5. Write a program to get max paid employee of the organization using java stream?

Friday, January 17, 2020

Bootstrp + jQuery + news REST API example

Sample code snippet will help in understanding how to consume REST services using jQuery and displaying content using Bootstrap.

The directory structure:

Live : https://jsl-news.glitch.me/

newspp
   - css
         - main.css
  - js
       - news.js

  - index.html

main.css

 #subBtn{  
   margin-top: 13%;  
 }  


index.html

 <!doctype html>  
 <html lang="en">  
  <head>  
   <!-- Required meta tags -->  
   <meta charset="utf-8">  
   <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">  
   <!-- Bootstrap CSS -->  
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">  
   <link rel="stylesheet" href="css/main.css">  
   <title>News - Items</title>  
  </head>  
  <body>  
   <div class="py-3 bg-primary text-white text-center">  
     <h3>Search worldwide news with code</h3>  
     <p class="lead">Get breaking news headlines, and search for articles from over 30,000 news sources and blogs with our news API</p>  
   </div>  
   <div class="container">  
     <h5 class="text-muted text-center mt-2">Please select the details to get updated news</h5>  
     <div class="row">  
       <div class="col-md-3"></div>  
       <div class="col-md-3">  
         <label for="country">Select Country</label>  
         <select class="form-control" id="country">  
           <option value="in">India</option>  
           <option value="us">United State</option>  
           <option value="sg">Singapore</option>  
         </select>  
       </div>  
       <div class="col-md-3">  
         <label for="category">Select Category</label>  
         <select class="form-control" id="category">  
           <option value="sports">Sports</option>  
           <option value="health">Health</option>  
           <option value="business">Business</option>  
         </select>  
       </div>  
       <div class="col-md-3">  
         <button id="subBtn" class="btn btn-primary">Submit</button>  
       </div>  
     </div>  
     <!--New items-->  
     <div class="row mt-5">  
       <div class="col-md-6 offset-md-3" id="showResult">  
       </div>  
     </div>  
    </div>  
   <!-- Optional JavaScript -->  
   <!-- jQuery first, then Popper.js, then Bootstrap JS -->  
   <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>  
   <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>  
   <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>  
   <script src="js/news.js"></script>  
 </body>  
 </html>  


JavaScript: news.js

  const url = "https://newsapi.org/v2/top-headlines?";  
  const apikey = "5c636a468a90465aa7cab199265d7299";  // Change the key by registering with news api
 class News{  
   constructor(title,author,description,urlToImage){  
     this.title = title;  
     this.author = author;  
     this.description = description;  
     this.urlToImage = urlToImage;  
   }  
 }  
  subBtn = document.querySelector("#subBtn");  
 function showNews(news){  
   str ="";  
   count = 1;  
   for(let item of news){  
     str += `<b>#${count++}<br>  
     <div class="card mt-2 mb-2">  
     <img src="${item.urlToImage}" class="card-img-top" alt="...">  
     <div class="card-body">  
      <h5 class="card-title">${item.title}</h5>  
      <p class="card-text">  
      <b>${item.author}</b>  
      <br>  
      ${item.description}  
      </p>  
      <a href="#" class="btn btn-primary">Go somewhere</a>  
     </div>  
    </div>  
    `  
   }  
   document.querySelector("#showResult").innerHTML = str;  
 }  
 subBtn.addEventListener('click',(e)=>{  
     let countryName = document.querySelector("#country").value;  
     let categoryValue = document.querySelector("#category").value;  
     let reqURL = `${url}country=${countryName}&apiKey=${apikey}&category=${categoryValue}`;  
     fetch(reqURL).then(rawData=>{  
       return rawData.json();  
     }).then(data=>{  
       news = [];  
       articles = data["articles"];  
          for(let article of articles){  
         newsItem = new News(article.title,article.author,article.description,article.urlToImage);  
         news.push(newsItem);  
       }  
       showNews(news);  
     }).catch(error=>{  
       alert("While getting news we got ",error);  
     })  
  })  

 Sample output:





Spring Boot 3 : JWT with SecurityFilterChain, AuthorizeHttpRequests, RequestMatchers

pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"...