HopsworksRMAppSecurityActions extends AbstractSecurityActions implements RMAppSecurityActions { @Override public String generateJWT(JWTSecurityHandler.JWTMaterialParameter jwtParameter) throws IOException, GeneralSecurityException { if (!jwtConfigured) { jwtNotConfigured("generateJWT"); } CloseableHttpResponse response = null; try { Matcher matcher = SUBJECT_USERNAME.matcher(jwtParameter.getAppUser()); String username = matcher.matches() ? matcher.group(2) : jwtParameter.getAppUser(); ServiceJWTManager.JWTDTO payload = new ServiceJWTManager.JWTDTO(); payload.setSubject(username); payload.setKeyName(jwtParameter.getApplicationId().toString()); payload.setAudiences(String.join(",", jwtParameter.getAudiences())); payload.setExpiresAt(DateUtils.localDateTime2Date(jwtParameter.getExpirationDate())); payload.setNbf(DateUtils.localDateTime2Date(jwtParameter.getValidNotBefore())); payload.setRenewable(jwtParameter.isRenewable()); payload.setExpLeeway(jwtParameter.getExpLeeway()); HttpPost request = new HttpPost(jwtGeneratePath); request.setEntity(new StringEntity(parser.toJson(payload)));; response = doJSONCall(request, "Hopsworks could not generate JWT for " + jwtParameter.getAppUser() + "/" + jwtParameter.getApplicationId().toString()); ServiceJWTManager.JWTDTO jwtResponse = parser.fromJson(EntityUtils.toString(response.getEntity()), ServiceJWTManager.JWTDTO.class); return jwtResponse.getToken(); } finally { if (response != null) { response.close(); } } } HopsworksRMAppSecurityActions(); @Override X509SecurityHandler.CertificateBundle sign(PKCS10CertificationRequest csr); @Override int revoke(String certificateIdentifier); @Override String generateJWT(JWTSecurityHandler.JWTMaterialParameter jwtParameter); @Override String renewJWT(JWTSecurityHandler.JWTMaterialParameter jwtParameter); @Override void invalidateJWT(String signingKeyName); static final String REVOKE_CERT_ID_PARAM; }
@Test public void testGenerateJWT() throws Exception { ApplicationId appId = ApplicationId.newInstance(System.currentTimeMillis(), 1); JWTSecurityHandler.JWTMaterialParameter jwtParam = createJWTParameter(appId); RMAppSecurityActions actor = (RMAppSecurityActions) HopsSecurityActionsFactory.getInstance().getActor(conf, conf.get(YarnConfiguration.HOPS_RM_SECURITY_ACTOR_KEY, YarnConfiguration.HOPS_RM_SECURITY_ACTOR_DEFAULT)); String jwt = actor.generateJWT(jwtParam); Assert.assertNotNull(jwt); String[] tokenizedSubject = JWT_SUBJECT.split("__"); JWT decoded = JWTParser.parse(jwt); String subject = decoded.getJWTClaimsSet().getSubject(); Assert.assertEquals(tokenizedSubject[1], subject); appId = ApplicationId.newInstance(System.currentTimeMillis(), 2); jwtParam = new JWTSecurityHandler.JWTMaterialParameter(appId, "dorothy"); jwtParam.setRenewable(false); LocalDateTime now = DateUtils.getNow(); LocalDateTime expiresAt = now.plus(10L, ChronoUnit.MINUTES); jwtParam.setExpirationDate(expiresAt); jwtParam.setValidNotBefore(now); jwtParam.setAudiences(new String[]{"job"}); jwt = actor.generateJWT(jwtParam); decoded = JWTParser.parse(jwt); subject = decoded.getJWTClaimsSet().getSubject(); Assert.assertEquals("dorothy", subject); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"); LocalDateTime nbfFromToken = DateUtils.date2LocalDateTime(decoded.getJWTClaimsSet().getNotBeforeTime()); Assert.assertEquals(now.format(formatter), nbfFromToken.format(formatter)); LocalDateTime expirationFromToken = DateUtils.date2LocalDateTime(decoded.getJWTClaimsSet().getExpirationTime()); Assert.assertEquals(expiresAt.format(formatter), expirationFromToken.format(formatter)); }
@Test public void testGenerateJWTSameSigningKeyShouldFail() throws Exception { ApplicationId appId = ApplicationId.newInstance(System.currentTimeMillis(), 1); JWTSecurityHandler.JWTMaterialParameter jwtParam = createJWTParameter(appId); RMAppSecurityActions actor = (RMAppSecurityActions) HopsSecurityActionsFactory.getInstance().getActor(conf, conf.get(YarnConfiguration.HOPS_RM_SECURITY_ACTOR_KEY, YarnConfiguration.HOPS_RM_SECURITY_ACTOR_DEFAULT)); actor.generateJWT(jwtParam); rule.expect(IOException.class); actor.generateJWT(jwtParam); }