📘 Table of Contents

  1. Why Authentication Matters
  2. JWT (JSON Web Token)
  3. OAuth 1.0
  4. OAuth 2.0
  5. OpenID Connect
  6. When to Use What?
  7. Final Thoughts

✅ Why Authentication Matters

Modern web applications often expose APIs that must be protected from unauthorized access. Whether it’s login, social login, or federated identity, understanding these mechanisms is crucial for building secure apps.


🔐 JWT (JSON Web Token)

💡 What is JWT?

JWT is a stateless token format where the server issues a token (usually after login) and the client sends it in each request's header.

🧰 Dependencies (Maven)

io.jsonwebtoken
    jjwt
    0.9.1


    org.springframework.boot
    spring-boot-starter-security

🔧 JWT Utility Class

@Component
public class JwtUtil {
    private final String SECRET = "secret_key";

    public String generateToken(String username) {
        return Jwts.builder()
            .setSubject(username)
            .setIssuedAt(new Date())
            .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 1 day
            .signWith(SignatureAlgorithm.HS256, SECRET)
            .compact();
    }

    public String extractUsername(String token) {
        return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody().getSubject();
    }

    public boolean validateToken(String token, UserDetails userDetails) {
        return extractUsername(token).equals(userDetails.getUsername());
    }
}

🔐 JWT Request Filter

public class JwtRequestFilter extends OncePerRequestFilter {
    @Autowired private JwtUtil jwtUtil;
    @Autowired private UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        final String authHeader = request.getHeader("Authorization");

        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String jwt = authHeader.substring(7);
            String username = jwtUtil.extractUsername(jwt);

            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = userDetailsService.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);
                }
            }
        }
        chain.doFilter(request, response);
    }
}

🔐 Security Configuration

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired private JwtRequestFilter jwtRequestFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests().antMatchers("/auth/**").permitAll()
            .anyRequest().authenticated();

        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }
}

🔐 OAuth 1.0

📌 What is OAuth 1.0?

OAuth 1.0 is a legacy authentication mechanism where the client signs each request. Still used by Twitter and a few legacy APIs.

✅ Using ScribeJava for OAuth 1.0

📦 Dependency

com.github.scribejava
    scribejava-apis
    8.3.1

🔄 Code Example

OAuth10aService service = new ServiceBuilder("your_consumer_key")
    .apiSecret("your_consumer_secret")
    .callback("http://localhost:8080/callback")
    .build(TwitterApi.instance());

OAuth1RequestToken requestToken = service.getRequestToken();
System.out.println("Authorize at: " + service.getAuthorizationUrl(requestToken));

Scanner scanner = new Scanner(System.in);
System.out.print("Enter the PIN: ");
String oauthVerifier = scanner.nextLine();

OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier);
System.out.println("Access Token: " + accessToken.getToken());

🔐 OAuth 2.0

📌 What is OAuth 2.0?

OAuth 2.0 is a widely used authorization framework that allows third-party apps to access a user's resources without exposing credentials.

🧰 Dependencies

org.springframework.boot
    spring-boot-starter-oauth2-client


    org.springframework.boot
    spring-boot-starter-oauth2-resource-server

⚙️ application.yml

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: your-client-id
            client-secret: your-client-secret
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
            scope: profile, email

🔒 Security Config

@Configuration
@EnableWebSecurity
public class OAuth2LoginSecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests(authz -> authz
                .anyRequest().authenticated())
            .oauth2Login();
        return http.build();
    }
}

🔐 OpenID Connect

📌 What is OpenID Connect?

OIDC is built on top of OAuth 2.0 and adds an identity layer. It’s used for login and identity verification.

If you want login + profile info from Google, OIDC is the way.

✅ Configuration (Same as OAuth 2.0)

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            scope: openid, profile, email

🧑‍💼 Accessing User Info

@Controller
public class UserController {
    @GetMapping("/user")
    @ResponseBody
    public Map<String, Object> user(@AuthenticationPrincipal OidcUser principal) {
        return Map.of(
            "email", principal.getEmail(),
            "name", principal.getFullName()
        );
    }
}

⚖️ When to Use What?

Use Case Recommended Approach
Stateless APIs JWT
Social Login OAuth 2.0
Federated Identity OpenID Connect
Legacy APIs (e.g. Twitter) OAuth 1.0

💬 Final Thoughts

Securing your application is not optional. The choice between JWT, OAuth, and OpenID depends on your specific needs—whether it’s identity, access, or both.

📌 Pro Tip: Always validate and expire tokens properly. Never expose client secrets or tokens in frontend code.