package com.micromata.webengineering.demo.authentication;
import com.micromata.webengineering.demo.user.User;
import com.micromata.webengineering.demo.user.UserService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class AuthenticationService {
private static final Logger LOG = LoggerFactory.getLogger(AuthenticationService.class);
@Autowired
private UserService userService;
@Value("${authenticationService.jwt.secret}")
private String JWTSecret;
@Value("${authenticationService.salt}")
private String salt;
/**
* Return object containing a valid user and his corresponding JWT token.
*/
public static class UserToken {
public User user;
public String token;
}
/**
* Create a JWT token and additional user information if the user's credentails are valid.
*
* @param email email
* @param password password
* @return a UserToken or null if the credentials are not valid
*/
public UserToken login(String email, String password) {
String hashedPassword = hashPassword(password);
User user = userService.getUser(email, hashedPassword);
if (user == null) {
LOG.info("User unable to login. user={}", email);
return null;
}
LOG.info("User successfully logged in. user={}", email);
String token = Jwts.builder()
.setSubject(email)
.setId(user.getId().toString())
.signWith(SignatureAlgorithm.HS512, JWTSecret)
.compact();
UserToken userToken = new UserToken();
userToken.user = user;
userToken.token = token;
return userToken;
}
/**
* Validate that a token is valid and returns its body.
*
* Throws a SignatureException if the token is not valid.
* @param jwtToken JWT token
* @return JWT body
*/
public Object parseToken(String jwtToken) {
LOG.debug("Parsing JWT token. JWTtoken={}", jwtToken);
return Jwts.parser()
.setSigningKey(JWTSecret)
.parse(jwtToken)
.getBody();
}
/**
* Return (salt + password) hashed with SHA-512.
*
* The salt is configured in the property authenticationService.salt.
*
* @param password plain text password
* @return hashed password
*/
private String hashPassword(String password) {
return DigestUtils.sha512Hex(salt + password);
}
}