String sign(Map<String, Object> claims, Integer expiresInSecond);
@Override public boolean verifyToken(Request request, String token, CsrfToken expected) throws CsrfTokenExpiredException { try { return null == token ? false : tokenEncoder.verifyToken(token); } catch (TokenExpiredException e) { throw new CsrfTokenExpiredException(e.getMessage()); } }
protected boolean verifyTokenSignature(String token, String expires, String signed) { return sign(token, expires).equals(signed); }
JwtVerifier verifier = rsc.getJwtVerifier(); if(verifier == null){ throw new TokenVerifyException(TokenVerifyException.ErrorCode.VERIFY_FAILED, "the jwt verifier must be specified!"); Map<String,Object> jwtDetail = verifier.verify(token.getToken()); SimpleResAccessTokenDetails resAccessTokenDetails = new SimpleResAccessTokenDetails();
@Override public boolean authenticate(CredentialsAuthenticationContext context, Credentials credentials, Out<UserPrincipal> user) throws AuthenticationException { if(credentials instanceof TokenCredentials) { String token = ((TokenCredentials) credentials).getToken(); Map<String, Object> claims = verifier.verify(token);
protected Map<String, Object> verify(String content, String payload, String signature) { if (!verifySignature(content, signature)) { throw new TokenVerifyException(ErrorCode.INVALID_SIGNATURE, "Signature verification failed"); } JsonValue json; try { json = JSON.parse(JWT.base64UrlDeocodeToString(payload)); } catch (Exception e) { throw new TokenVerifyException(ErrorCode.INVALID_PAYLOAD, "Parse payload as json object failed, " + e.getMessage()); } if (!json.isMap()) { throw new TokenVerifyException(ErrorCode.INVALID_PAYLOAD, "The payload must be json object '{..}'"); } //get claims Map<String, Object> claims = json.asMap(); //verify expiration verifyExpiration(claims); return claims; }
protected State handleOAuth2ServerSuccess(Request request, Response response, OAuth2Params params) throws Throwable { AccessToken at = null; if(config.isLoginWithAccessToken()) { String code = params.getCode(); if(Strings.isEmpty(code)) { return error(request, response, "illegal_state", "code required from oauth2 server"); } at = codeVerifier.verifyCode(code); if(null == at) { return error(request, response, "illegal_state", "invalid authorization code"); } } String idToken = params.getIdToken(); if(Strings.isEmpty(idToken)) { return error(request, response, "illegal_state", "id_token required from oauth2 server"); } try{ IdToken credentials = idTokenVerifier.verifyIdToken(params, idToken); Authentication authc = authenticate(params, credentials, at); login(request, response, authc); return State.CONTINUE; }catch (TokenVerifyException e) { return error(request, response, e.getErrorCode().name(), e.getMessage()); } }
@Override public Map<String, Object> verify(String token) throws TokenVerifyException { Args.notEmpty(token, "token"); String[] parts = Strings.split(token, '.'); if (parts.length < 2 || parts.length > 3) { throw new TokenVerifyException(ErrorCode.INVALID_TOKEN, "Invalid jwt token, wrong number of parts: " + parts.length); } String content; String payload; String signature; if (parts.length == 2) { content = parts[0]; payload = parts[0]; signature = parts[1]; } else { content = parts[0] + "." + parts[1]; payload = parts[1]; signature = parts[2]; } if (payload.isEmpty() || signature.isEmpty()) { throw new TokenVerifyException(ErrorCode.INVALID_TOKEN, "Invalid jwt token, both payload and signature parts must not be empty"); } return verify(content, payload, signature); }
TokenCredentials credentials = new SimpleTokenCredentials(token); Out<UserPrincipal> outPrincipal = new Out<>(); try { log.info("Token verify error, " + e.getMessage(), e); removeCookie(request, response); return Result.empty();
verifyTokenExpired(expires); return verifyTokenSignature(token, expires, signed);
errorHandler.handleInvalidToken(request, response, e.getMessage()); return State.INTERCEPTED; } catch (OAuth2ResponseException e) {
protected void verifyTokenExpired(String expires) throws TokenExpiredException { long expirationTime = Long.parseLong(expires); long now = System.currentTimeMillis(); if(expirationTime > 0 && now - expirationTime > 0) { throw new TokenExpiredException("Token expired, expration time '" + expirationTime + "', current time '" + now + "'"); } }
static byte[] sign(String alg, SecretKey key, String data) { try { Mac mac = Mac.getInstance(alg); mac.init(key); return mac.doFinal(data.getBytes()); } catch (Exception e) { throw new TokenSignatureException("Error signing data using algorithm '" + alg + ", " + e.getMessage(), e); } }
@Override public String encodeToken(String token) { String expires = String.valueOf(expiresInSeconds > 0 ? System.currentTimeMillis() + expiresInSeconds * 1000 : 0); return doEncodeToken(token, expires); }
protected String doGenerateToken() { String value = String.valueOf(counter.incrementAndGet()); return tokenEncoder.encodeToken(value); }
@Override public void postCreate(BeanFactory factory) throws Throwable { if(null == tokenEncoder) { tokenEncoder = new SimpleTokenEncoder(sc.getSecret(), sc.getDefaultAuthenticationExpires()); } } }
/** * token + ":" + expires + ":" + md5Hex(token + ":" + expires + ":" + secret) */ protected String doEncodeToken(String token, String expires) { Args.assertFalse(token.contains(":"), "The token must not contains character ':'"); String encoded = token + ":" + expires + ":" + sign(token, expires) ; //removes all the '=' characters StringBuilder sb = new StringBuilder(Base64.encode(encoded)); while (sb.charAt(sb.length() - 1) == '=') { sb.deleteCharAt(sb.length() - 1); } return sb.toString(); }
protected void verifyExpiration(Map<String, Object> claims) { Object exp = claims.get(JWT.CLAIM_EXPIRATION_TIME); if (null != exp && exp instanceof Number) { long expirationTimeSecond = ((Number) exp).longValue(); long nowTimeInSecond = System.currentTimeMillis()/1000L; if(expirationTimeSecond <= 0 || nowTimeInSecond >= expirationTimeSecond){ throw new TokenExpiredException("Token expired"); } } }
static byte[] sign(String alg, RSAPrivateKey key, String data) { try { Signature signature = Signature.getInstance(alg); signature.initSign(key); signature.update(data.getBytes()); return signature.sign(); } catch (GeneralSecurityException e) { throw new TokenSignatureException("Error signing data using algorithm '" + alg + ", " + e.getMessage(), e); } }