bezkoder / spring-boot-security-jwt-auth-mongodb Goto Github PK
View Code? Open in Web Editor NEWBuild Spring Boot MongoDB JWT Authentication & Authorization example with Spring Security, Spring Data
Build Spring Boot MongoDB JWT Authentication & Authorization example with Spring Security, Spring Data
Hey, your repo looks very helpful to people working with spring boot security. Awesome job!
Currently, there is no license in the repository, which means that technically people cannot use your code, which makes it not-open-source.
Would you consider adding a license to this repository?
I would advise to add MIT license, if you want people do whatever they want with your code.
If you are unsure how to choose a license, you can check out https://choosealicense.com/
There is no chance to update this repo to new Spring Boot 2.7.0?
If you find the following exception:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed;
nested exception is org.springframework.data.mongodb.UncategorizedMongoDbException:
Query failed with error code 2 and error message 'Field 'locale' is invalid in: { locale: "roles" }' on server localhost:27017;
nested exception is com.mongodb.MongoQueryException:
Query failed with error code 2 and error message 'Field 'locale' is invalid in: { locale: "roles" }' on server localhost:27017] with root cause
you can use @Document("roles")
instead of @Document(collection = "roles")
in Role.java,
and @Document("users")
instead of @Document(collection = "users")
in User.java.
This issue record the problems in programming, and the solutions that I used.
In security/jwt/JwtUtils.java
.signWith(SignatureAlgorithm.HS512, jwtSecret)
will use JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey) throws InvalidKeyException;
method.
This method will use base64 decoder to decode base64EncodedSecretKey, so the length of jwtSecret in application.properties
could not be too short, if the length of secret string is not enough, the program may throw the following exception:
io.jsonwebtoken.security.WeakKeyException: The signing key's size is xxx bits which is not secure enough for the HS512 algorithm.
The JWT JWA Specification (RFC 7518, Section 3.2) states that keys used with HS512 MUST have a size >= 512 bits (the key size must be greater than or equal to the hash output size).
Consider using the io.jsonwebtoken.security.Keys class's 'secretKeyFor(SignatureAlgorithm.HS512)' method to create a key guaranteed to be secure enough for HS512.
See https://tools.ietf
To solve this exception, I should provide long enough secret string, futher more, I'd like to use origin secret string instead of Base64 encoded string, so I use JwtBuilder signWith(SignatureAlgorithm alg, byte[] secretKey) throws InvalidKeyException;
method, and the code in JwtUtils.java like this:
return Jwts.builder()
.setSubject((userPrincipal.getUsername()))
.setIssuedAt(new Date())
.setExpiration(new Date((new Date().getTime() + jwtExpirationMs)))
.signWith(SignatureAlgorithm.HS512, jwtSecret.getBytes(StandardCharsets.UTF_8))
.compact();
and in application.properties file, jwtSecret contains at least 64 chars.
I noticed that signWith(SignatureAlgorithm alg, byte[] secretKey)
, signWith(SignatureAlgorithm alg, String base64EncodedSecretKey)
and Jwts.parser()
are deprecated in jjwt 0.11.5, so I use new methods, the code in JwtUtils.java like this:
@Component
public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
@Value("${indicatorManagement.app.jwtSecret}")
private String jwtSecret;
@Value("${indicatorManagement.app.jwtExpirationMs}")
private int jwtExpirationMs;
public String generateJwtToken(Authentication authentication) {
UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
return Jwts.builder()
.setSubject((userPrincipal.getUsername()))
.setIssuedAt(new Date())
.setExpiration(new Date((new Date().getTime() + jwtExpirationMs)))
// .signWith(SignatureAlgorithm.HS512, jwtSecret.getBytes(StandardCharsets.UTF_8))
.signWith(Keys.hmacShaKeyFor(jwtSecret.getBytes(StandardCharsets.UTF_8)), SignatureAlgorithm.HS512)
.compact();
}
public String getUserNameFromJwtToken(String token) {
// return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
return Jwts.parserBuilder()
.setSigningKey(jwtSecret.getBytes(StandardCharsets.UTF_8))
.build().parseClaimsJws(token).getBody().getSubject();
}
public boolean validateJwtToken(String authToken) {
try {
// Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
Jwts.parserBuilder().setSigningKey(jwtSecret.getBytes(StandardCharsets.UTF_8))
.build().parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
logger.error("Invalid JWT signature: {}", e.getMessage());
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("JWT claims string is empty: {}", e.getMessage());
}
return false;
}
}
Technology
Java 11.0.15
Spring Boot 2.6.7 (with Spring Security, Spring Data MongoDB)
jjwt 0.11.5
MongoDB 4.4.12
Maven 3.8.1
PS: Thanks to the author for the great spring boot examples.
I already added role to mongoDB. But still Role not found.
docker exec -it mongodb mongosh
db.roles.insertMany([
{ name: "ROLE_USER" },
{ name: "ROLE_MODERATOR" },
{ name: "ROLE_ADMIN" },
])
Then my body request like this:
{
"username": "naruto",
"email": "[email protected]",
"roles": [
"user", "mod"
],
"password": "Naruto2024!"
}
Any suggestion?
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.