* Fix: Failed authentication #1704 * Update account.html
This commit is contained in:
parent
6c9a4e8acc
commit
81e2a77e57
5 changed files with 42 additions and 28 deletions
|
@ -2,6 +2,8 @@ package stirling.software.SPDF.config.security;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
@ -9,6 +11,7 @@ import org.springframework.context.annotation.Lazy;
|
|||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.session.SessionInformation;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
@ -22,6 +25,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
||||
import stirling.software.SPDF.model.ApiKeyAuthenticationToken;
|
||||
import stirling.software.SPDF.model.User;
|
||||
|
||||
@Component
|
||||
public class UserAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
@ -54,15 +58,20 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
|
|||
try {
|
||||
// Use API key to authenticate. This requires you to have an authentication
|
||||
// provider for API keys.
|
||||
UserDetails userDetails = userService.loadUserByApiKey(apiKey);
|
||||
if (userDetails == null) {
|
||||
Optional<User> user = userService.loadUserByApiKey(apiKey);
|
||||
if (!user.isPresent()) {
|
||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
response.getWriter().write("Invalid API Key.");
|
||||
return;
|
||||
}
|
||||
authentication =
|
||||
new ApiKeyAuthenticationToken(
|
||||
userDetails, apiKey, userDetails.getAuthorities());
|
||||
List<SimpleGrantedAuthority> authorities =
|
||||
user.get().getAuthorities().stream()
|
||||
.map(
|
||||
authority ->
|
||||
new SimpleGrantedAuthority(
|
||||
authority.getAuthority()))
|
||||
.collect(Collectors.toList());
|
||||
authentication = new ApiKeyAuthenticationToken(user.get(), apiKey, authorities);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
} catch (AuthenticationException e) {
|
||||
// If API key authentication fails, deny the request
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.springframework.security.crypto.password.PasswordEncoder;
|
|||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import stirling.software.SPDF.config.DatabaseBackupInterface;
|
||||
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
|
||||
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
|
||||
|
@ -65,8 +66,8 @@ public class UserService implements UserServiceInterface {
|
|||
}
|
||||
|
||||
public Authentication getAuthentication(String apiKey) {
|
||||
User user = getUserByApiKey(apiKey);
|
||||
if (user == null) {
|
||||
Optional<User> user = getUserByApiKey(apiKey);
|
||||
if (!user.isPresent()) {
|
||||
throw new UsernameNotFoundException("API key is not valid");
|
||||
}
|
||||
|
||||
|
@ -74,7 +75,7 @@ public class UserService implements UserServiceInterface {
|
|||
return new UsernamePasswordAuthenticationToken(
|
||||
user, // principal (typically the user)
|
||||
null, // credentials (we don't expose the password or API key here)
|
||||
getAuthorities(user) // user's authorities (roles/permissions)
|
||||
getAuthorities(user.get()) // user's authorities (roles/permissions)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -89,17 +90,17 @@ public class UserService implements UserServiceInterface {
|
|||
String apiKey;
|
||||
do {
|
||||
apiKey = UUID.randomUUID().toString();
|
||||
} while (userRepository.findByApiKey(apiKey) != null); // Ensure uniqueness
|
||||
} while (userRepository.findByApiKey(apiKey).isPresent()); // Ensure uniqueness
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
public User addApiKeyToUser(String username) {
|
||||
User user =
|
||||
findByUsernameIgnoreCase(username)
|
||||
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
|
||||
|
||||
user.setApiKey(generateApiKey());
|
||||
return userRepository.save(user);
|
||||
Optional<User> user = findByUsernameIgnoreCase(username);
|
||||
if (user.isPresent()) {
|
||||
user.get().setApiKey(generateApiKey());
|
||||
return userRepository.save(user.get());
|
||||
}
|
||||
throw new UsernameNotFoundException("User not found");
|
||||
}
|
||||
|
||||
public User refreshApiKeyForUser(String username) {
|
||||
|
@ -114,21 +115,18 @@ public class UserService implements UserServiceInterface {
|
|||
}
|
||||
|
||||
public boolean isValidApiKey(String apiKey) {
|
||||
return userRepository.findByApiKey(apiKey) != null;
|
||||
return userRepository.findByApiKey(apiKey).isPresent();
|
||||
}
|
||||
|
||||
public User getUserByApiKey(String apiKey) {
|
||||
public Optional<User> getUserByApiKey(String apiKey) {
|
||||
return userRepository.findByApiKey(apiKey);
|
||||
}
|
||||
|
||||
public UserDetails loadUserByApiKey(String apiKey) {
|
||||
User user = userRepository.findByApiKey(apiKey);
|
||||
if (user != null) {
|
||||
// Convert your User entity to a UserDetails object with authorities
|
||||
return new org.springframework.security.core.userdetails.User(
|
||||
user.getUsername(),
|
||||
user.getPassword(), // you might not need this for API key auth
|
||||
getAuthorities(user));
|
||||
public Optional<User> loadUserByApiKey(String apiKey) {
|
||||
Optional<User> user = userRepository.findByApiKey(apiKey);
|
||||
|
||||
if (user.isPresent()) {
|
||||
return user;
|
||||
}
|
||||
return null; // or throw an exception
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package stirling.software.SPDF.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
|
@ -11,7 +13,9 @@ import jakarta.persistence.Table;
|
|||
|
||||
@Entity
|
||||
@Table(name = "authorities")
|
||||
public class Authority {
|
||||
public class Authority implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Authority() {}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package stirling.software.SPDF.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
@ -23,7 +24,9 @@ import jakarta.persistence.Table;
|
|||
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
public class User {
|
||||
public class User implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
|
|
@ -13,5 +13,5 @@ public interface UserRepository extends JpaRepository<User, Long> {
|
|||
|
||||
Optional<User> findByUsername(String username);
|
||||
|
||||
User findByApiKey(String apiKey);
|
||||
Optional<User> findByApiKey(String apiKey);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue