Search in sources :

Example 1 with TokenMetadata

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;
}
Also used : TokenMetadata(org.apache.knox.gateway.services.security.token.TokenMetadata)

Example 2 with TokenMetadata

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;
}
Also used : SQLException(java.sql.SQLException) UnknownTokenException(org.apache.knox.gateway.services.security.token.UnknownTokenException) TokenMetadata(org.apache.knox.gateway.services.security.token.TokenMetadata)

Example 3 with 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());
}
Also used : AbstractAliasService(org.apache.knox.gateway.services.security.AbstractAliasService) AliasService(org.apache.knox.gateway.services.security.AliasService) ArrayList(java.util.ArrayList) EasyMock.anyString(org.easymock.EasyMock.anyString) TokenMetadata(org.apache.knox.gateway.services.security.token.TokenMetadata) JWTToken(org.apache.knox.gateway.services.security.token.impl.JWTToken) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 4 with TokenMetadata

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);
}
Also used : AbstractAliasService(org.apache.knox.gateway.services.security.AbstractAliasService) AliasService(org.apache.knox.gateway.services.security.AliasService) EasyMock.anyString(org.easymock.EasyMock.anyString) TokenMetadata(org.apache.knox.gateway.services.security.token.TokenMetadata) JWTToken(org.apache.knox.gateway.services.security.token.impl.JWTToken) TokenStateJournal(org.apache.knox.gateway.services.token.state.TokenStateJournal) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 5 with TokenMetadata

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);
}
Also used : JWT(org.apache.knox.gateway.services.security.token.impl.JWT) UnknownTokenException(org.apache.knox.gateway.services.security.token.UnknownTokenException) TokenStateService(org.apache.knox.gateway.services.security.token.TokenStateService) TokenMetadata(org.apache.knox.gateway.services.security.token.TokenMetadata) Test(org.junit.Test)

Aggregations

TokenMetadata (org.apache.knox.gateway.services.security.token.TokenMetadata)14 Test (org.junit.Test)5 HashMap (java.util.HashMap)4 UnknownTokenException (org.apache.knox.gateway.services.security.token.UnknownTokenException)3 JWTToken (org.apache.knox.gateway.services.security.token.impl.JWTToken)3 EasyMock.anyString (org.easymock.EasyMock.anyString)3 HashSet (java.util.HashSet)2 Map (java.util.Map)2 AbstractAliasService (org.apache.knox.gateway.services.security.AbstractAliasService)2 AliasService (org.apache.knox.gateway.services.security.AliasService)2 TokenStateService (org.apache.knox.gateway.services.security.token.TokenStateService)2 JWT (org.apache.knox.gateway.services.security.token.impl.JWT)2 Field (java.lang.reflect.Field)1 KeyStoreException (java.security.KeyStoreException)1 Principal (java.security.Principal)1 Certificate (java.security.cert.Certificate)1 CertificateEncodingException (java.security.cert.CertificateEncodingException)1 X509Certificate (java.security.cert.X509Certificate)1 Connection (java.sql.Connection)1 PreparedStatement (java.sql.PreparedStatement)1