use of io.jenkins.blueocean.auth.jwt.JwtAuthenticationStore in project blueocean-plugin by jenkinsci.
the class JwtAuthenticationServiceImpl method getToken.
@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.getAuthentication2();
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.get().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);
// set claim
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;
}
use of io.jenkins.blueocean.auth.jwt.JwtAuthenticationStore in project blueocean-plugin by jenkinsci.
the class JwtTokenVerifierImpl method validate.
/**
* @return
* null if the JWT token is not present
* @throws Exception
* if the JWT token is present but invalid
*/
@CheckForNull
private Authentication validate(HttpServletRequest request) {
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
return null;
}
String token = authHeader.substring("Bearer ".length());
JsonWebStructure jws = parse(token);
if (jws == null) {
return null;
}
try {
String alg = jws.getAlgorithmHeaderValue();
if (alg == null || !alg.equals(RSA_USING_SHA256)) {
logger.error(String.format("Invalid JWT token: unsupported algorithm in header, found %s, expected %s", alg, RSA_USING_SHA256));
throw new ServiceException.UnauthorizedException("Invalid JWT token");
}
String kid = jws.getKeyIdHeaderValue();
if (kid == null) {
logger.error("Invalid JWT token: missing kid");
throw new ServiceException.UnauthorizedException("Invalid JWT token");
}
SigningPublicKey publicKey = JwtSigningKeyProvider.toPublicKey(kid);
if (publicKey == null) {
throw new ServiceException.UnexpectedErrorException("Invalid kid=" + kid);
}
JwtConsumer jwtConsumer = new JwtConsumerBuilder().setRequireExpirationTime().setRequireJwtId().setAllowedClockSkewInSeconds(// allow some leeway in validating time based claims to account for clock skew
30).setRequireSubject().setVerificationKey(// verify the sign with the public key
publicKey.getKey()).build();
try {
JwtContext context = jwtConsumer.process(token);
JwtClaims claims = context.getJwtClaims();
String subject = claims.getSubject();
if (subject.equals("anonymous")) {
// if anonymous, we do not bother checking expiration
return Jenkins.ANONYMOUS2;
} else {
// If not anonymous user, get Authentication object associated with this claim
// We give a change to the authentication store to inspect the claims and if expired it might
// do cleanup of associated Authentication object for example.
JwtAuthenticationStore authenticationStore = getJwtStore(claims.getClaimsMap());
Authentication authentication = authenticationStore.getAuthentication(claims.getClaimsMap());
// Now check if token expired
NumericDate expirationTime = claims.getExpirationTime();
if (expirationTime.isBefore(NumericDate.now())) {
throw new ServiceException.UnauthorizedException("Invalid JWT token: expired");
}
return authentication;
}
} catch (InvalidJwtException e) {
logger.error("Invalid JWT token: " + e.getMessage(), e);
throw new ServiceException.UnauthorizedException("Invalid JWT token");
} catch (MalformedClaimException e) {
logger.error(String.format("Error reading sub header for token %s", jws.getPayload()), e);
throw new ServiceException.UnauthorizedException("Invalid JWT token: malformed claim");
}
} catch (JoseException e) {
logger.error("Error parsing JWT token: " + e.getMessage(), e);
throw new ServiceException.UnauthorizedException("Invalid JWT Token: " + e.getMessage());
}
}
Aggregations