Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions AuthenticationService/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>gov.uspto</groupId>
<artifactId>PatentPublicData</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>

<artifactId>AuthenticationService</artifactId>

<packaging>jar</packaging>

<dependencies>
<!-- SLF4J Logging (consistent with other modules) -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>

<!-- Guava for utilities (consistent with other modules) -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>26.0-jre</version>
</dependency>

<!-- jBCrypt for password hashing (NIST 800-53 IA-5 compliance) -->
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>

<!-- Commons Codec for additional cryptographic utilities -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>

<!-- Commons Lang for utility functions -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>

<!-- Mockito for testing (Java 8 compatible) -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.12.4</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
<plugins>
<!-- Disable assembly plugin for this module -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>default</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package gov.uspto.auth.authenticator;

/**
* Exception thrown when authenticator management operations fail.
*
* NIST 800-53 Controls: IA-5 (Authenticator Management)
*/
public class AuthenticatorException extends Exception {

private static final long serialVersionUID = 1L;

public AuthenticatorException(String message) {
super(message);
}

public AuthenticatorException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package gov.uspto.auth.authenticator;

import gov.uspto.auth.core.Credential;

/**
* Interface for managing authenticators (passwords, tokens, certificates, etc.).
*
* This interface provides methods for creating, validating, updating, and revoking
* authenticators in compliance with NIST 800-53 IA-5 (Authenticator Management).
*
* NIST 800-53 Controls: IA-5 (Authenticator Management), IA-5(1) (Password-based Authentication)
*/
public interface AuthenticatorManager {

/**
* Creates a new authenticator for the specified identifier.
*
* @param identifier the user or service identifier
* @param credential the credential to create
* @throws AuthenticatorException if authenticator creation fails
*/
void createAuthenticator(String identifier, Credential credential) throws AuthenticatorException;

/**
* Validates an authenticator.
*
* @param identifier the user or service identifier
* @param credential the credential to validate
* @return true if the authenticator is valid, false otherwise
* @throws AuthenticatorException if validation fails
*/
boolean validateAuthenticator(String identifier, Credential credential) throws AuthenticatorException;

/**
* Updates an existing authenticator.
*
* @param identifier the user or service identifier
* @param oldCredential the old credential
* @param newCredential the new credential
* @throws AuthenticatorException if update fails
*/
void updateAuthenticator(String identifier, Credential oldCredential, Credential newCredential)
throws AuthenticatorException;

/**
* Revokes an authenticator.
*
* @param identifier the user or service identifier
* @throws AuthenticatorException if revocation fails
*/
void revokeAuthenticator(String identifier) throws AuthenticatorException;

/**
* Checks if an authenticator has expired.
*
* @param identifier the user or service identifier
* @return true if the authenticator has expired, false otherwise
* @throws AuthenticatorException if check fails
*/
boolean isAuthenticatorExpired(String identifier) throws AuthenticatorException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
package gov.uspto.auth.core;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Configuration properties for the authentication service.
*
* This class manages authentication policies, timeouts, retry limits, and other
* configuration parameters. Configuration can be loaded from properties files
* or environment variables.
*
* NIST 800-53 Controls: IA-5 (Authenticator Management), AC-7 (Unsuccessful Logon Attempts)
*/
public class AuthenticationConfig {

private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationConfig.class);

private static final String DEFAULT_CONFIG_FILE = "authentication.properties";

private int sessionTimeoutMinutes = 30;
private int maxLoginAttempts = 3;
private int accountLockoutDurationMinutes = 15;
private int passwordMinLength = 12;
private int passwordExpirationDays = 90;
private boolean requirePasswordComplexity = true;
private int tokenExpirationMinutes = 60;
private boolean enableAuditLogging = true;

/**
* Creates a default authentication configuration.
*/
public AuthenticationConfig() {
loadDefaults();
}

/**
* Creates an authentication configuration from a properties file.
*
* @param configFile the configuration file path
*/
public AuthenticationConfig(String configFile) {
loadFromFile(configFile);
}

/**
* Loads default configuration values.
*/
private void loadDefaults() {
LOGGER.info("Loading default authentication configuration");
}

/**
* Loads configuration from a properties file.
*
* @param configFile the configuration file path
*/
private void loadFromFile(String configFile) {
Properties props = new Properties();
try (InputStream input = getClass().getClassLoader().getResourceAsStream(configFile)) {
if (input != null) {
props.load(input);
loadFromProperties(props);
LOGGER.info("Loaded authentication configuration from file: {}", configFile);
} else {
LOGGER.warn("Configuration file not found: {}, using defaults", configFile);
loadDefaults();
}
} catch (IOException e) {
LOGGER.error("Error loading configuration file: {}", configFile, e);
loadDefaults();
}
}

/**
* Loads configuration from properties.
*
* @param props the properties to load from
*/
private void loadFromProperties(Properties props) {
sessionTimeoutMinutes = getIntProperty(props, "auth.session.timeout.minutes", sessionTimeoutMinutes);
maxLoginAttempts = getIntProperty(props, "auth.max.login.attempts", maxLoginAttempts);
accountLockoutDurationMinutes = getIntProperty(props, "auth.account.lockout.minutes", accountLockoutDurationMinutes);
passwordMinLength = getIntProperty(props, "auth.password.min.length", passwordMinLength);
passwordExpirationDays = getIntProperty(props, "auth.password.expiration.days", passwordExpirationDays);
requirePasswordComplexity = getBooleanProperty(props, "auth.password.require.complexity", requirePasswordComplexity);
tokenExpirationMinutes = getIntProperty(props, "auth.token.expiration.minutes", tokenExpirationMinutes);
enableAuditLogging = getBooleanProperty(props, "auth.audit.logging.enabled", enableAuditLogging);
}

/**
* Gets an integer property value with a default fallback.
*/
private int getIntProperty(Properties props, String key, int defaultValue) {
String value = System.getenv(key.replace('.', '_').toUpperCase());
if (value == null) {
value = props.getProperty(key);
}
if (value != null) {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
LOGGER.warn("Invalid integer value for {}: {}, using default: {}", key, value, defaultValue);
}
}
return defaultValue;
}

/**
* Gets a boolean property value with a default fallback.
*/
private boolean getBooleanProperty(Properties props, String key, boolean defaultValue) {
String value = System.getenv(key.replace('.', '_').toUpperCase());
if (value == null) {
value = props.getProperty(key);
}
if (value != null) {
return Boolean.parseBoolean(value);
}
return defaultValue;
}

public int getSessionTimeoutMinutes() {
return sessionTimeoutMinutes;
}

public void setSessionTimeoutMinutes(int sessionTimeoutMinutes) {
this.sessionTimeoutMinutes = sessionTimeoutMinutes;
}

public int getMaxLoginAttempts() {
return maxLoginAttempts;
}

public void setMaxLoginAttempts(int maxLoginAttempts) {
this.maxLoginAttempts = maxLoginAttempts;
}

public int getAccountLockoutDurationMinutes() {
return accountLockoutDurationMinutes;
}

public void setAccountLockoutDurationMinutes(int accountLockoutDurationMinutes) {
this.accountLockoutDurationMinutes = accountLockoutDurationMinutes;
}

public int getPasswordMinLength() {
return passwordMinLength;
}

public void setPasswordMinLength(int passwordMinLength) {
this.passwordMinLength = passwordMinLength;
}

public int getPasswordExpirationDays() {
return passwordExpirationDays;
}

public void setPasswordExpirationDays(int passwordExpirationDays) {
this.passwordExpirationDays = passwordExpirationDays;
}

public boolean isRequirePasswordComplexity() {
return requirePasswordComplexity;
}

public void setRequirePasswordComplexity(boolean requirePasswordComplexity) {
this.requirePasswordComplexity = requirePasswordComplexity;
}

public int getTokenExpirationMinutes() {
return tokenExpirationMinutes;
}

public void setTokenExpirationMinutes(int tokenExpirationMinutes) {
this.tokenExpirationMinutes = tokenExpirationMinutes;
}

public boolean isEnableAuditLogging() {
return enableAuditLogging;
}

public void setEnableAuditLogging(boolean enableAuditLogging) {
this.enableAuditLogging = enableAuditLogging;
}

@Override
public String toString() {
return "AuthenticationConfig{" +
"sessionTimeoutMinutes=" + sessionTimeoutMinutes +
", maxLoginAttempts=" + maxLoginAttempts +
", accountLockoutDurationMinutes=" + accountLockoutDurationMinutes +
", passwordMinLength=" + passwordMinLength +
", passwordExpirationDays=" + passwordExpirationDays +
", requirePasswordComplexity=" + requirePasswordComplexity +
", tokenExpirationMinutes=" + tokenExpirationMinutes +
", enableAuditLogging=" + enableAuditLogging +
'}';
}
}
Loading