JwtAuthenticationServiceImpl extends JwtAuthenticationService { @Override public JwtToken getToken(@Nullable @QueryParameter("expiryTimeInMins") Integer expiryTimeInMins, @Nullable @QueryParameter("maxExpiryTimeInMins") Integer maxExpiryTimeInMins) { long expiryTime= Long.getLong("EXPIRY_TIME_IN_MINS",DEFAULT_EXPIRY_IN_SEC); int maxExpiryTime = Integer.getInteger("MAX_EXPIRY_TIME_IN_MINS",DEFAULT_MAX_EXPIRY_TIME_IN_MIN); if(maxExpiryTimeInMins != null){ maxExpiryTime = maxExpiryTimeInMins; } if(expiryTimeInMins != null){ if(expiryTimeInMins > maxExpiryTime) { throw new ServiceException.BadRequestException( String.format("expiryTimeInMins %s can't be greater than %s", expiryTimeInMins, maxExpiryTime)); } expiryTime = expiryTimeInMins * 60; } Authentication authentication = Jenkins.getAuthentication(); String userId = authentication.getName(); User user = User.get(userId, false, Collections.emptyMap()); String email = null; String fullName = null; if(user != null) { fullName = user.getFullName(); userId = user.getId(); Mailer.UserProperty p = user.getProperty(Mailer.UserProperty.class); if(p!=null) email = p.getAddress(); } Plugin plugin = Jenkins.getInstance().getPlugin("blueocean-jwt"); String issuer = "blueocean-jwt:"+ ((plugin!=null) ? plugin.getWrapper().getVersion() : ""); JwtToken jwtToken = new JwtToken(); jwtToken.claim.put("jti", UUID.randomUUID().toString().replace("-","")); jwtToken.claim.put("iss", issuer); jwtToken.claim.put("sub", userId); jwtToken.claim.put("name", fullName); long currentTime = System.currentTimeMillis()/1000; jwtToken.claim.put("iat", currentTime); jwtToken.claim.put("exp", currentTime+expiryTime); jwtToken.claim.put("nbf", currentTime - DEFAULT_NOT_BEFORE_IN_SEC); JSONObject context = new JSONObject(); JSONObject userObject = new JSONObject(); userObject.put("id", userId); userObject.put("fullName", fullName); userObject.put("email", email); JwtAuthenticationStore authenticationStore = getJwtStore(authentication); authenticationStore.store(authentication, context); context.put("user", userObject); jwtToken.claim.put("context", context); return jwtToken; }  @Override JwtToken getToken(@Nullable @QueryParameter("expiryTimeInMins") Integer expiryTimeInMins, @Nullable @QueryParameter("maxExpiryTimeInMins") Integer maxExpiryTimeInMins); @Override JSONObject getJwkSet(); @Override String getIconFileName(); @Override String getDisplayName(); static JwtAuthenticationStore getJwtStore(Authentication authentication);  }
@Test public void getToken() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); User user = User.get("alice"); user.setFullName("Alice Cooper"); user.addProperty(new Mailer.UserProperty("alice@jenkins-ci.org")); JenkinsRule.WebClient webClient = j.createWebClient(); webClient.login("alice"); String token = getToken(webClient); Assert.assertNotNull(token); JsonWebStructure jsonWebStructure = JsonWebStructure.fromCompactSerialization(token); Assert.assertTrue(jsonWebStructure instanceof JsonWebSignature); JsonWebSignature jsw = (JsonWebSignature) jsonWebStructure; System.out.println(token); System.out.println(jsw.toString()); String kid = jsw.getHeader("kid"); Assert.assertNotNull(kid); Page page = webClient.goTo("jwt-auth/jwks/"+kid+"/", "application/json"); JSONObject jsonObject = JSONObject.fromObject(page.getWebResponse().getContentAsString()); System.out.println(jsonObject.toString()); RsaJsonWebKey rsaJsonWebKey = new RsaJsonWebKey(jsonObject,null); JwtConsumer jwtConsumer = new JwtConsumerBuilder() .setRequireExpirationTime() .setAllowedClockSkewInSeconds(30) .setRequireSubject() .setVerificationKey(rsaJsonWebKey.getKey()) .build(); JwtClaims claims = jwtConsumer.processToClaims(token); Assert.assertEquals("alice",claims.getSubject()); Map<String,Object> claimMap = claims.getClaimsMap(); Map<String,Object> context = (Map<String, Object>) claimMap.get("context"); Map<String,String> userContext = (Map<String, String>) context.get("user"); Assert.assertEquals("alice", userContext.get("id")); Assert.assertEquals("Alice Cooper", userContext.get("fullName")); Assert.assertEquals("alice@jenkins-ci.org", userContext.get("email")); }
@Test public void anonymousUserToken() throws Exception{ j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); JenkinsRule.WebClient webClient = j.createWebClient(); String token = getToken(webClient); Assert.assertNotNull(token); JsonWebStructure jsonWebStructure = JsonWebStructure.fromCompactSerialization(token); Assert.assertTrue(jsonWebStructure instanceof JsonWebSignature); JsonWebSignature jsw = (JsonWebSignature) jsonWebStructure; String kid = jsw.getHeader("kid"); Assert.assertNotNull(kid); Page page = webClient.goTo("jwt-auth/jwks/"+kid+"/", "application/json"); JSONObject jsonObject = JSONObject.fromObject(page.getWebResponse().getContentAsString()); RsaJsonWebKey rsaJsonWebKey = new RsaJsonWebKey(jsonObject,null); JwtConsumer jwtConsumer = new JwtConsumerBuilder() .setRequireExpirationTime() .setAllowedClockSkewInSeconds(30) .setRequireSubject() .setVerificationKey(rsaJsonWebKey.getKey()) .build(); JwtClaims claims = jwtConsumer.processToClaims(token); Assert.assertEquals("anonymous",claims.getSubject()); Map<String,Object> claimMap = claims.getClaimsMap(); Map<String,Object> context = (Map<String, Object>) claimMap.get("context"); Map<String,String> userContext = (Map<String, String>) context.get("user"); Assert.assertEquals("anonymous", userContext.get("id")); }
@Test public void getJwks() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); JenkinsRule.WebClient webClient = j.createWebClient(); User user = User.get("alice"); user.setFullName("Alice Cooper"); user.addProperty(new Mailer.UserProperty("alice@jenkins-ci.org")); webClient.login("alice"); String token = getToken(webClient); String jwksPayload = webClient.goTo("jwt-auth/jwk-set", "application/json").getWebResponse().getContentAsString(); System.out.println(jwksPayload); JsonWebKeySet jsonWebKeySet = new JsonWebKeySet(jwksPayload); JwksVerificationKeyResolver jwksResolver = new JwksVerificationKeyResolver(jsonWebKeySet.getJsonWebKeys()); JwtConsumer jwtConsumer = new JwtConsumerBuilder() .setRequireExpirationTime() .setAllowedClockSkewInSeconds(30) .setRequireSubject() .setVerificationKeyResolver(jwksResolver) .build(); JwtClaims claims = jwtConsumer.processToClaims(token); Assert.assertEquals("alice", claims.getSubject()); Map<String,Object> claimMap = claims.getClaimsMap(); Map<String,Object> context = (Map<String, Object>) claimMap.get("context"); Map<String,String> userContext = (Map<String, String>) context.get("user"); Assert.assertEquals("alice", userContext.get("id")); Assert.assertEquals("Alice Cooper", userContext.get("fullName")); Assert.assertEquals("alice@jenkins-ci.org", userContext.get("email")); }