diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java index 93ca46c36e87..4d6928c53508 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java @@ -513,7 +513,11 @@ private void loadTokenSecretState( LOG.info("Loading token state into token manager."); for (Map.Entry entry : state.getTokenState().entrySet()) { - addPersistedDelegationToken(entry.getKey(), entry.getValue()); + try { + addPersistedDelegationToken(entry.getKey(), entry.getValue()); + } catch (Exception e) { + LOG.error("exception while loading delegation token from DB... ignored to continue startup", e); + } } } @@ -528,6 +532,16 @@ private void addPersistedDelegationToken(OzoneTokenIdentifier identifier, byte[] password; if (StringUtils.isNotEmpty(identifier.getSecretKeyId())) { ManagedSecretKey signKey = secretKeyClient.getSecretKey(UUID.fromString(identifier.getSecretKeyId())); + if (signKey == null) { + // if delegation token expired, remove it from the store. + if (renewDate < Time.now()) { + LOG.info("Removing expired persisted delegation token {} from DB", identifier); + this.store.removeToken(identifier); + } + + throw new IOException("Secret key " + UUID.fromString(identifier.getSecretKeyId()) + + " not found for token " + formatTokenId(identifier)); + } password = signKey.sign(identifier.getBytes()); } else { if (LOG.isDebugEnabled()) { diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSecretManager.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSecretManager.java index fe7b2d18e9d3..941167191193 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSecretManager.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestOzoneDelegationTokenSecretManager.java @@ -26,8 +26,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableList; @@ -231,6 +235,43 @@ public void testCreateToken() throws Exception { validateHash(token.getPassword(), token.getIdentifier()); } + @Test + public void testExpiredSecretKey() throws Exception { + SecretKeyClient old = secretKeyClient; + secretKeyClient = spy(secretKeyClient); + doReturn(null).when(secretKeyClient).getSecretKey(any()); + + Text tester = new Text("tester"); + OzoneTokenIdentifier identifier = + new OzoneTokenIdentifier(tester, tester, tester); + identifier.setSecretKeyId(UUID.randomUUID().toString()); + identifier.setOmServiceId(OzoneConsts.OM_SERVICE_ID_DEFAULT); + + // case 1: Secret key not found, and delegation token is valid. + om.getMetadataManager().getDelegationTokenTable().put(identifier, Long.MAX_VALUE); + try { + secretManager = createSecretManager(conf, TOKEN_MAX_LIFETIME, + expiryTime, TOKEN_REMOVER_SCAN_INTERVAL); + om.getMetadataManager().getDelegationTokenTable().delete(identifier); + + // case 2: Secret key not found, and delegation token is expired. + OzoneTokenIdentifier identifier2 = + new OzoneTokenIdentifier(tester, tester, tester); + identifier2.setSecretKeyId(UUID.randomUUID().toString()); + identifier2.setOmServiceId(OzoneConsts.OM_SERVICE_ID_DEFAULT); + + om.getMetadataManager().getDelegationTokenTable().put(identifier2, Time.now() - 1); + secretManager = createSecretManager(conf, TOKEN_MAX_LIFETIME, + expiryTime, TOKEN_REMOVER_SCAN_INTERVAL); + // expired token should be removed from the table. + assertFalse(om.getMetadataManager().getDelegationTokenTable().isExist(identifier2), + "Expired token " + identifier2 + " should be removed from the table"); + } finally { + verify(secretKeyClient, times(2)).getSecretKey(any()); + secretKeyClient = old; + } + } + private void restartSecretManager() throws IOException { secretManager.stop(); secretManager = null;