📘 Table of Contents
- Why Authentication Matters
- JWT (JSON Web Token)
- OAuth 1.0
- OAuth 2.0
- OpenID Connect
- When to Use What?
- 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.