implement users resource and email based auth
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
fea42d33eb
commit
4990b5b92c
@ -36,7 +36,6 @@ public class Main {
|
|||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
|
||||||
users.forEach(user -> LOGGER.info("ID: {}, Name: {}", user.getUuid(), user.getUsername()));
|
users.forEach(user -> LOGGER.info("ID: {}, Name: {}", user.getUuid(), user.getUsername()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Thread shutdownHook = new Thread(() -> {
|
private static final Thread shutdownHook = new Thread(() -> {
|
||||||
|
@ -24,7 +24,7 @@ public class ApplicationConfiguration
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
UserDetailsService userDetailsService() {
|
UserDetailsService userDetailsService() {
|
||||||
return username -> userRepository.findByEmail(username)
|
return email -> userRepository.findByEmail(email)
|
||||||
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
|
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,13 +9,13 @@ import org.springframework.lang.NonNull;
|
|||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
|
||||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||||
|
import wtf.beatrice.releasehive.model.User;
|
||||||
import wtf.beatrice.releasehive.service.JWTService;
|
import wtf.beatrice.releasehive.service.JWTService;
|
||||||
|
import wtf.beatrice.releasehive.service.UserDetailsExtendedService;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@ -25,11 +25,11 @@ public class JWTAuthenticationFilter extends OncePerRequestFilter
|
|||||||
private final HandlerExceptionResolver handlerExceptionResolver;
|
private final HandlerExceptionResolver handlerExceptionResolver;
|
||||||
|
|
||||||
private final JWTService jwtService;
|
private final JWTService jwtService;
|
||||||
private final UserDetailsService userDetailsService;
|
private final UserDetailsExtendedService userDetailsService;
|
||||||
|
|
||||||
public JWTAuthenticationFilter(
|
public JWTAuthenticationFilter(
|
||||||
@Autowired JWTService jwtService,
|
@Autowired JWTService jwtService,
|
||||||
@Autowired UserDetailsService userDetailsService,
|
@Autowired UserDetailsExtendedService userDetailsService,
|
||||||
@Autowired HandlerExceptionResolver handlerExceptionResolver) {
|
@Autowired HandlerExceptionResolver handlerExceptionResolver) {
|
||||||
this.jwtService = jwtService;
|
this.jwtService = jwtService;
|
||||||
this.userDetailsService = userDetailsService;
|
this.userDetailsService = userDetailsService;
|
||||||
@ -52,12 +52,12 @@ public class JWTAuthenticationFilter extends OncePerRequestFilter
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final String jwt = authHeader.substring(7);
|
final String jwt = authHeader.substring(7);
|
||||||
final String userEmail = jwtService.extractUsername(jwt);
|
final String email = jwtService.extractEmail(jwt);
|
||||||
|
|
||||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
|
||||||
if (userEmail != null && authentication == null) {
|
if (email != null && authentication == null) {
|
||||||
UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail);
|
User userDetails = this.userDetailsService.loadUserByEmail(email);
|
||||||
|
|
||||||
if (jwtService.isTokenValid(jwt, userDetails)) {
|
if (jwtService.isTokenValid(jwt, userDetails)) {
|
||||||
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
|
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
|
||||||
|
@ -11,4 +11,6 @@ import java.util.UUID;
|
|||||||
public interface UserRepository extends JpaRepository<User, UUID> {
|
public interface UserRepository extends JpaRepository<User, UUID> {
|
||||||
|
|
||||||
Optional<User> findByEmail(String email);
|
Optional<User> findByEmail(String email);
|
||||||
|
|
||||||
|
Optional<User> findByUsername(String username);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
package wtf.beatrice.releasehive.resource;
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import wtf.beatrice.releasehive.model.User;
|
||||||
|
import wtf.beatrice.releasehive.service.UserService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/users")
|
||||||
|
public class UserResource
|
||||||
|
{
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
public UserResource(@Autowired UserService userService)
|
||||||
|
{
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(
|
||||||
|
value = "/me",
|
||||||
|
produces = "application/json")
|
||||||
|
public ResponseEntity<User> authenticatedUser() {
|
||||||
|
|
||||||
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
User currentUser = (User) authentication.getPrincipal();
|
||||||
|
|
||||||
|
return ResponseEntity.ok(currentUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(
|
||||||
|
value = "/all",
|
||||||
|
produces = "application/json")
|
||||||
|
public ResponseEntity<List<User>> getAllUsers() {
|
||||||
|
List<User> users = userService.getAllUsers();
|
||||||
|
return ResponseEntity.ok(users);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,8 +6,8 @@ import io.jsonwebtoken.SignatureAlgorithm;
|
|||||||
import io.jsonwebtoken.io.Decoders;
|
import io.jsonwebtoken.io.Decoders;
|
||||||
import io.jsonwebtoken.security.Keys;
|
import io.jsonwebtoken.security.Keys;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import wtf.beatrice.releasehive.model.User;
|
||||||
|
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -24,7 +24,7 @@ public class JWTService
|
|||||||
@Value("${security.jwt.expiration-time}")
|
@Value("${security.jwt.expiration-time}")
|
||||||
private long jwtExpiration;
|
private long jwtExpiration;
|
||||||
|
|
||||||
public String extractUsername(String token) {
|
public String extractEmail(String token) {
|
||||||
return extractClaim(token, Claims::getSubject);
|
return extractClaim(token, Claims::getSubject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,11 +33,11 @@ public class JWTService
|
|||||||
return claimsResolver.apply(claims);
|
return claimsResolver.apply(claims);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String generateToken(UserDetails userDetails) {
|
public String generateToken(User userDetails) {
|
||||||
return generateToken(new HashMap<>(), userDetails);
|
return generateToken(new HashMap<>(), userDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String generateToken(Map<String, Object> extraClaims, UserDetails userDetails) {
|
public String generateToken(Map<String, Object> extraClaims, User userDetails) {
|
||||||
return buildToken(extraClaims, userDetails, jwtExpiration);
|
return buildToken(extraClaims, userDetails, jwtExpiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,22 +47,22 @@ public class JWTService
|
|||||||
|
|
||||||
private String buildToken(
|
private String buildToken(
|
||||||
Map<String, Object> extraClaims,
|
Map<String, Object> extraClaims,
|
||||||
UserDetails userDetails,
|
User userDetails,
|
||||||
long expiration
|
long expiration
|
||||||
) {
|
) {
|
||||||
return Jwts
|
return Jwts
|
||||||
.builder()
|
.builder()
|
||||||
.setClaims(extraClaims)
|
.setClaims(extraClaims)
|
||||||
.setSubject(userDetails.getUsername())
|
.setSubject(userDetails.getEmail())
|
||||||
.setIssuedAt(new Date(System.currentTimeMillis()))
|
.setIssuedAt(new Date(System.currentTimeMillis()))
|
||||||
.setExpiration(new Date(System.currentTimeMillis() + expiration))
|
.setExpiration(new Date(System.currentTimeMillis() + expiration))
|
||||||
.signWith(getSignInKey(), SignatureAlgorithm.HS256)
|
.signWith(getSignInKey(), SignatureAlgorithm.HS256)
|
||||||
.compact();
|
.compact();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTokenValid(String token, UserDetails userDetails) {
|
public boolean isTokenValid(String token, User userDetails) {
|
||||||
final String username = extractUsername(token);
|
final String email = extractEmail(token);
|
||||||
return (username.equals(userDetails.getUsername())) && !isTokenExpired(token);
|
return (email.equals(userDetails.getEmail())) && !isTokenExpired(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTokenExpired(String token) {
|
private boolean isTokenExpired(String token) {
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package wtf.beatrice.releasehive.service;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import wtf.beatrice.releasehive.model.User;
|
||||||
|
import wtf.beatrice.releasehive.repository.UserRepository;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserDetailsExtendedService {
|
||||||
|
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
public UserDetailsExtendedService(@Autowired UserRepository userRepository) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
return userRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException(username));
|
||||||
|
}
|
||||||
|
|
||||||
|
public User loadUserByEmail(String email) throws UsernameNotFoundException {
|
||||||
|
return userRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException(email));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package wtf.beatrice.releasehive.service;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import wtf.beatrice.releasehive.model.User;
|
||||||
|
import wtf.beatrice.releasehive.repository.UserRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserService
|
||||||
|
{
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
public UserService(@Autowired UserRepository userRepository) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<User> getAllUsers() {
|
||||||
|
return userRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user