Java
/
Spring Boot
- 1 Basics 9
-
Classes S
-
Objects S
-
Arrays S
-
Variables S
-
Loops S
-
Numbers S
-
Strings S
-
Exceptions S
-
Regexp S
- 2 OOP 9
-
Inheritance
-
Polymorphism
-
Static S
-
Abstract
-
Interfaces
-
Constructors S
-
Packages
-
Nested Classes
-
Final
- 3 Compiler 2
-
Sublime Text S
-
Apache Ant
- 4 Collections 8
-
Lists
-
Comparable S
-
Sets
-
Maps
-
Generics
-
Properties
-
Streams
-
Json
- 5 Threads 4
-
Create Thread S
-
Sleep
-
Lock
-
Scheduler
- 6 Design Patterns 4
-
Singleton
-
Observer
-
Strategy
-
Mediator
- 7 Swing 12
-
Frame
-
Panel
-
Listener
-
Combo Box
-
Label
-
Image
-
Menu
-
Table
-
Layout
-
Drawing
-
Timer
-
Designer
- 8 I/O 7
-
Streams IO
-
Socket
-
Watching Files
-
Mail
-
Logger
-
Clipboard
-
Encrypt S
- 9 Effective 7
-
Constructors S
-
Dependency Injection
-
Composition
-
Interfaces Default
-
Import Static S
-
Enums
-
Lambdas
- 10 Junit 5
-
About Junit S
-
Test Case
-
Suite Test
-
Annotations
-
Exceptions
- 11 Lambdas 7
-
Expressions S
-
Functional Interfaces
-
Streams
-
Common Operations
-
Default Methods
-
Static Methods S
-
Single Responsibility
- 12 JavaFX 6
-
Openjfx
-
Scene Builder
-
First App
-
Jar Archive
-
On Action
-
Change Listener
- 13 Maven 4
-
Demo
-
Spring Boot
-
Junit
-
Guava
- 14 Spring Boot 13
-
Quick start S
-
Rest service S
-
Consuming rest S
-
Templates S
-
Security auth S
-
Command line S
-
Scheduled task S
-
Ajax S
-
Jdbc mysql S
-
Encrypt password S
-
Https S
-
Jwt S
-
Post request S
S
R
Q
Java Spring Boot Jwt
Token auth using jjwt library curl -H "Authorization: Bearer $TOKEN" $URL
App
Web Spring application with token auth, jjwt dependency.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
<dependencies>

package com.minte9.jwt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
Controller
REST controller that implements the auth with username/password.
/**
* REST Controller
*
* In real-life applciations will have three servers: our API,
* authentication sever, authorization server. As demo, we can implement
* all three functionalities in a single application.
*
* With Jwts builder() we create the JWT token with: user's name, authorities,
* issued and expiration dates, and signature.
*
* In Spring Security, GrantedAuthority is an interface that represents
* a granted authority or permission (ROLE_USER, ROLE_ADMIN, etc)
*/
package com.minte9.jwt;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
@RestController
public class AppRestController {
@ Autowired
private Environment env;
@RequestMapping("/hello")
public String hello() {
return "Hello World! \n";
}
@PostMapping("/token")
public User genToken(
@RequestParam("user") String username,
@RequestParam("password") String pwd) {
User user = new User();
user.setUser(username);
String envUser = env.getProperty("spring.security.user.name");
String envPass = env.getProperty("spring.security.user.password");
if(username.equals(envUser) && pwd.equals(envPass)) { // Look Here
String token = getJWTToken(username);
user.setToken(token);
}
return user;
}
private String getJWTToken(String username) {
String secretKey = "myTokenSecretKey";
List<GrantedAuthority> grantedAuthorities = AuthorityUtils
.commaSeparatedStringToAuthorityList("ROLE_USER");
String token = Jwts
.builder()
.setId("minte9JWT")
.setSubject(username)
.claim("authorities", grantedAuthorities.stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList()))
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + 600000))
.signWith(SignatureAlgorithm.HS512, secretKey.getBytes())
.compact();
return "Bearer " + token;
}
}
Config
Calls to /user are allowed, but all other calls require authentication.
/**
* JWT Authorization Security Configuration
*
* Extend WebSecurityConfigurerAdapter class to provide
* custom security configuration.
*
* Add JWT authorization filter after UsernamePasswordAuthenticationFilter.
* Allow unauthenticated access to /token POST requests.
* Require authentication for all other requests.
*/
package com.minte9.jwt;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.*;
import org.springframework.security.web.authentication.*;
@EnableWebSecurity
@Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.addFilterAfter(
new JWTAuthorizationFilter(),
UsernamePasswordAuthenticationFilter.class // Look Here
)
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/token").permitAll()
.anyRequest().authenticated();
}
}
Authorization
Implement the autorization process with JWTAuthorizationFilter class.
/**
* JWT Authorization
*
* JSON Web Token is an open source standard for creating access tokens
* that allow us to secure communications between client and server.
*
* Token authentication is more secure than session authentication
* because a token cannot be tampered with.
*/
package com.minte9.jwt;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.*;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.UnsupportedJwtException;
public class JWTAuthorizationFilter extends OncePerRequestFilter {
private final String HEADER = "Authorization";
private final String PREFIX = "Bearer ";
private final String SECRET = "myTokenSecretKey";
/**
* Intercept HTTP requests and performs JWT token authentication.
*
* If the token is valid, it sets up Spring authentication by setting
* the security context with the authenticated user's information.
*
* If the token is invalid, it clears the authentication context.
* If an exception occurs during validation, it returns a 403
*/
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain chain)
throws ServletException, IOException {
try {
if (checkJWTToken(request, response)) {
Claims claims = validateToken(request);
if (claims.get("authorities") != null) {
setUpSpringAuthentication(claims);
} else {
SecurityContextHolder.clearContext();
}
}else {
SecurityContextHolder.clearContext();
}
chain.doFilter(request, response);
} catch (ExpiredJwtException |
UnsupportedJwtException | MalformedJwtException e) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response = (HttpServletResponse) response;
response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
return;
}
}
/**
* Extract the JWT token from the HTTP request header and parses it
* to retrieve the token's claims.
*
* It returns the token's claims after validating the token's signature
* using the application's secret key.
*/
private Claims validateToken(HttpServletRequest request) {
String jwtToken = request.getHeader(HEADER).replace(PREFIX, "");
JwtParser jwtParser = Jwts.parser();
jwtParser.setSigningKey(SECRET.getBytes());
return jwtParser.parseClaimsJws(jwtToken).getBody();
}
/**
* Set up Spring authentication instance with the authenticated
* user's details and setting it in the security context.
*/
private void setUpSpringAuthentication(Claims claims) {
@SuppressWarnings("unchecked")
List<String> authorities = (List<String>) claims.get("authorities");
UsernamePasswordAuthenticationToken auth =
new UsernamePasswordAuthenticationToken(
claims.getSubject(), null, authorities.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList()
)
);
SecurityContextHolder.getContext().setAuthentication(auth);
}
/**
* Checks if the Authorization header of the HTTP request contains
* a JWT token with the correct Bearer prefix.
*/
private boolean checkJWTToken(
HttpServletRequest request,
HttpServletResponse res) {
String authenticationHeader = request.getHeader(HEADER);
if ( authenticationHeader == null ||
!authenticationHeader.startsWith(PREFIX))
return false;
return true;
}
}
Token
The client uses token to access the protected resources.
curl http://localhost:8080/hello
# Access denied
URL='http://localhost:8080/token?user=myuser&password=mypass'
RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" $URL)
TOKEN=$(echo $RESPONSE | jq -r '.token')
echo $TOKEN
# Bearer eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiJzb2Z0dG...
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/hello
# Hello World
➥ Questions