use of org.apache.knox.gateway.services.security.token.TokenMetadata in project knox by apache.
the class AbstractJWTFilter method validatePasscode.
private boolean validatePasscode(String tokenId, String passcode) throws UnknownTokenException {
final long issueTime = tokenStateService.getTokenIssueTime(tokenId);
final TokenMetadata tokenMetadata = tokenStateService.getTokenMetadata(tokenId);
final String userName = tokenMetadata == null ? "" : tokenMetadata.getUserName();
final byte[] storedPasscode = tokenMetadata == null ? null : tokenMetadata.getPasscode().getBytes(UTF_8);
final boolean validPasscode = Arrays.equals(tokenMAC.hash(tokenId, issueTime, userName, passcode).getBytes(UTF_8), storedPasscode);
if (validPasscode) {
recordSignatureVerification(passcode);
}
return validPasscode;
}
use of org.apache.knox.gateway.services.security.token.TokenMetadata in project knox by apache.
the class JDBCTokenStateService method getTokenMetadata.
@Override
public TokenMetadata getTokenMetadata(String tokenId) throws UnknownTokenException {
// To support HA, there is no in-memory lookup here; we should go directly to the DB.
// See KNOX-2658 for more details.
TokenMetadata tokenMetadata = null;
try {
tokenMetadata = tokenDatabase.getTokenMetadata(tokenId);
if (tokenMetadata != null) {
log.fetchedMetadataFromDatabase(Tokens.getTokenIDDisplayText(tokenId));
// Update the in-memory cache to avoid subsequent DB look-ups for the same state
super.addMetadata(tokenId, tokenMetadata);
} else {
throw new UnknownTokenException(tokenId);
}
} catch (SQLException e) {
log.errorFetchingMetadataFromDatabase(Tokens.getTokenIDDisplayText(tokenId), e.getMessage(), e);
}
return tokenMetadata;
}
use of org.apache.knox.gateway.services.security.token.TokenMetadata in project knox by apache.
the class AliasBasedTokenStateServiceTest method testAddAndRemoveTokenIncludesCache.
@Test
public void testAddAndRemoveTokenIncludesCache() throws Exception {
final int TOKEN_COUNT = 10;
final Set<JWTToken> testTokens = new HashSet<>();
for (int i = 0; i < TOKEN_COUNT; i++) {
testTokens.add(createMockToken(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(60)));
}
Set<String> testTokenStateAliases = new HashSet<>();
for (JWTToken token : testTokens) {
String tokenId = token.getClaim(JWTToken.KNOX_ID_CLAIM);
testTokenStateAliases.add(tokenId);
testTokenStateAliases.add(tokenId + AliasBasedTokenStateService.TOKEN_MAX_LIFETIME_POSTFIX);
testTokenStateAliases.add(tokenId + AliasBasedTokenStateService.TOKEN_META_POSTFIX);
testTokenStateAliases.add(tokenId + AliasBasedTokenStateService.TOKEN_ISSUE_TIME_POSTFIX);
}
// Create a mock AliasService so we can verify that the expected bulk removal method is invoked (and that the
// individual removal method is NOT invoked) when the token state reaper runs.
AliasService aliasService = EasyMock.createMock(AliasService.class);
EasyMock.expect(aliasService.getAliasesForCluster(AliasService.NO_CLUSTER_NAME)).andReturn(new ArrayList<>(testTokenStateAliases)).anyTimes();
// Expecting the bulk alias removal method to be invoked only once, rather than the individual alias removal method
// invoked twice for every expired token.
aliasService.removeAliasesForCluster((EasyMock.eq(AliasService.NO_CLUSTER_NAME)), EasyMock.eq(testTokenStateAliases));
EasyMock.expectLastCall().andVoid().once();
// expecting this call when loading credentials from the keystore on startup
EasyMock.expect(aliasService.getPasswordsForGateway()).andReturn(Collections.emptyMap()).anyTimes();
EasyMock.replay(aliasService);
AliasBasedTokenStateService tss = new AliasBasedTokenStateService();
tss.setAliasService(aliasService);
initTokenStateService(tss);
Map<String, Long> tokenExpirations = getTokenExpirationsField(tss, false);
Map<String, Long> maxTokenLifetimes = getMaxTokenLifetimesField(tss, false);
Map<String, Map<String, TokenMetadata>> metadata = getMetadataMapField(tss, false);
Map<String, Long> tokenIssueTimes = getTokenIssueTimesField(tss, false);
final long evictionInterval = TimeUnit.SECONDS.toMillis(3);
final long maxTokenLifetime = evictionInterval * 3;
try {
tss.start();
// Add the expired tokens
for (JWTToken token : testTokens) {
tss.addToken(token.getClaim(JWTToken.KNOX_ID_CLAIM), System.currentTimeMillis(), token.getExpiresDate().getTime(), maxTokenLifetime);
tss.addMetadata(token.getClaim(JWTToken.KNOX_ID_CLAIM), new TokenMetadata("alice"));
}
assertEquals("Expected the tokens to have been added in the base class cache.", TOKEN_COUNT, tokenExpirations.size());
assertEquals("Expected the tokens lifetimes to have been added in the base class cache.", TOKEN_COUNT, maxTokenLifetimes.size());
assertEquals("Expected the token metadata to have been added in the base class cache.", TOKEN_COUNT, metadata.size());
assertEquals("Expected the token issue times to have been added in the base class cache.", TOKEN_COUNT, tokenIssueTimes.size());
// Sleep to allow the eviction evaluation to be performed
Thread.sleep(evictionInterval + (evictionInterval / 4));
} finally {
tss.stop();
}
// Verify that the expected methods were invoked
EasyMock.verify(aliasService);
assertEquals("Expected the tokens to have been removed from the base class cache as a result of eviction.", 0, tokenExpirations.size());
assertEquals("Expected the tokens lifetimes to have been removed from the base class cache as a result of eviction.", 0, maxTokenLifetimes.size());
assertEquals("Expected the token metadata to have been removed from the base class cache as a result of eviction.", 0, metadata.size());
assertEquals("Expected the token issue times to have been removed from the base class cache as a result of eviction.", 0, tokenIssueTimes.size());
}
use of org.apache.knox.gateway.services.security.token.TokenMetadata in project knox by apache.
the class AliasBasedTokenStateServiceTest method testLoadTokenStateJournalDuringInitWithInvalidEntries.
@Test
public void testLoadTokenStateJournalDuringInitWithInvalidEntries() throws Exception {
final int TOKEN_COUNT = 5;
AliasService aliasService = EasyMock.createMock(AliasService.class);
aliasService.getAliasesForCluster(anyString());
EasyMock.expectLastCall().andReturn(Collections.emptyList()).anyTimes();
EasyMock.replay(aliasService);
// Create some test tokens
final Set<JWTToken> testTokens = new HashSet<>();
for (int i = 0; i < TOKEN_COUNT; i++) {
JWTToken token = createMockToken(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(60));
testTokens.add(token);
}
// Persist the token state journal entries before initializing the TokenStateService
TokenStateJournal journal = TokenStateJournalFactory.create(createMockGatewayConfig(false));
for (JWTToken token : testTokens) {
journal.add(token.getClaim(JWTToken.KNOX_ID_CLAIM), System.currentTimeMillis(), token.getExpiresDate().getTime(), System.currentTimeMillis() + TimeUnit.HOURS.toMillis(24), null);
}
// Add an entry with an invalid token identifier
journal.add(" ", System.currentTimeMillis(), System.currentTimeMillis(), System.currentTimeMillis(), null);
// Add an entry with an invalid issue time
journal.add(new TestJournalEntry(UUID.randomUUID().toString(), "invalidLongValue", String.valueOf(System.currentTimeMillis()), String.valueOf(System.currentTimeMillis()), new TokenMetadata("testUser")));
// Add an entry with an invalid expiration time
journal.add(new TestJournalEntry(UUID.randomUUID().toString(), String.valueOf(System.currentTimeMillis()), "invalidLongValue", String.valueOf(System.currentTimeMillis()), new TokenMetadata("testUser")));
// Add an entry with an invalid max lifetime
journal.add(new TestJournalEntry(UUID.randomUUID().toString(), String.valueOf(System.currentTimeMillis()), String.valueOf(System.currentTimeMillis()), "invalidLongValue", new TokenMetadata("testUser")));
AliasBasedTokenStateService tss = new NoEvictionAliasBasedTokenStateService();
tss.setAliasService(aliasService);
// Initialize the service, and presumably load the previously-persisted journal entries
initTokenStateService(tss);
Map<String, Long> tokenExpirations = getTokenExpirationsField(tss);
Map<String, Long> maxTokenLifetimes = getMaxTokenLifetimesField(tss);
Map<String, Long> tokenIssueTimes = getTokenIssueTimesField(tss, true);
Set<AliasBasedTokenStateService.TokenState> unpersistedState = getUnpersistedStateField(tss);
assertEquals("Expected the tokens expirations to have been added in the base class cache.", TOKEN_COUNT, tokenExpirations.size());
assertEquals("Expected the tokens lifetimes to have been added in the base class cache.", TOKEN_COUNT, maxTokenLifetimes.size());
assertEquals("Expected the tokens issue times to have been added in the base class cache.", TOKEN_COUNT, tokenIssueTimes.size());
assertEquals("Expected the unpersisted state to have been added.", // Two TokenState entries per token (expiration, max lifetime, issue time)
(TOKEN_COUNT * 3), unpersistedState.size());
// Verify that the expected methods were invoked
EasyMock.verify(aliasService);
}
use of org.apache.knox.gateway.services.security.token.TokenMetadata in project knox by apache.
the class DefaultTokenStateServiceTest method testAddTokenMetadata.
@SuppressWarnings("PMD.JUnitUseExpected")
@Test
public void testAddTokenMetadata() throws Exception {
final JWT token = getJWTToken(System.currentTimeMillis());
final String tokenId = token.getClaim(JWTToken.KNOX_ID_CLAIM);
final TokenStateService tss = new DefaultTokenStateService();
tss.addToken((JWTToken) token, System.currentTimeMillis());
try {
tss.getTokenMetadata(tokenId);
fail("Expected exception since there is no metadata for the token ID.");
} catch (UnknownTokenException e) {
// Expected
}
final String userName = "testUser";
tss.addMetadata(token.getClaim(JWTToken.KNOX_ID_CLAIM), new TokenMetadata(userName));
assertNotNull(tss.getTokenMetadata(tokenId));
assertEquals(tss.getTokenMetadata(tokenId).getUserName(), userName);
assertNull(tss.getTokenMetadata(tokenId).getComment());
final String comment = "this is my test comment";
tss.addMetadata(token.getClaim(JWTToken.KNOX_ID_CLAIM), new TokenMetadata(userName, comment, true));
assertNotNull(tss.getTokenMetadata(tokenId));
assertEquals(tss.getTokenMetadata(tokenId).getComment(), comment);
assertTrue(tss.getTokenMetadata(tokenId).isEnabled());
final String passcode = "myPasscode";
final TokenMetadata metadata = new TokenMetadata(userName, comment, true);
metadata.setPasscode(passcode);
tss.addMetadata(token.getClaim(JWTToken.KNOX_ID_CLAIM), metadata);
assertNotNull(tss.getTokenMetadata(tokenId));
assertEquals(tss.getTokenMetadata(tokenId).getPasscode(), passcode);
}
Aggregations