Java tutorial
/* * Copyright (C) 2016 R&D Solutions Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.hawkcd.utilities.deserializers; import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.JsonObject; import io.hawkcd.model.User; import io.hawkcd.model.payload.TokenInfo; import net.oauth.jsontoken.Checker; import net.oauth.jsontoken.JsonToken; import net.oauth.jsontoken.JsonTokenParser; import net.oauth.jsontoken.crypto.HmacSHA256Signer; import net.oauth.jsontoken.crypto.HmacSHA256Verifier; import net.oauth.jsontoken.crypto.SignatureAlgorithm; import net.oauth.jsontoken.crypto.Verifier; import net.oauth.jsontoken.discovery.VerifierProvider; import net.oauth.jsontoken.discovery.VerifierProviders; import java.security.InvalidKeyException; import java.security.SignatureException; import java.time.Instant; import java.time.LocalDateTime; import java.util.Calendar; import java.util.TimeZone; public class TokenAdapter { private static final String AUDIENCE = "NotReallyImportant"; private static final String ISSUER = "hawkCD"; private static final String SIGNING_KEY = "LongAndHardToGuessValueWithSpecialCharacters@^($%*$%"; private static Gson gson = new Gson(); public static String createJsonWebToken(User user, Long durationDays) { //Current time and signing algorithm Calendar cal = Calendar.getInstance(); HmacSHA256Signer signer; try { signer = new HmacSHA256Signer(ISSUER, null, SIGNING_KEY.getBytes()); } catch (InvalidKeyException e) { throw new RuntimeException(e); } //Configure JSON token JsonToken token = new JsonToken(signer); token.setAudience(AUDIENCE); token.setIssuedAt(new org.joda.time.Instant(cal.getTimeInMillis())); token.setExpiration( new org.joda.time.Instant(cal.getTimeInMillis() + (1000L * 60L * 60L * 24L * durationDays))); //Configure request object, which provides information of the item JsonObject request = new JsonObject(); String userAsString = gson.toJson(user); request.addProperty("user", userAsString); JsonObject payload = token.getPayloadAsJsonObject(); payload.add("info", request); try { return token.serializeAndSign(); } catch (SignatureException e) { throw new RuntimeException(e); } } public static TokenInfo verifyToken(String token) { if (token == null) { return null; } try { final Verifier hmacVerifier = new HmacSHA256Verifier(SIGNING_KEY.getBytes()); VerifierProvider hmacLocator = (id, key) -> Lists.newArrayList(hmacVerifier); VerifierProviders locators = new VerifierProviders(); locators.setVerifierProvider(SignatureAlgorithm.HS256, hmacLocator); Checker checker = payload -> { }; JsonTokenParser jsonTokenParser = new JsonTokenParser(locators, checker); JsonToken jsonToken; try { jsonToken = jsonTokenParser.verifyAndDeserialize(token); } catch (SignatureException | IllegalArgumentException e) { return null; // throw new RuntimeException(e); } JsonObject payload = jsonToken.getPayloadAsJsonObject(); TokenInfo t = new TokenInfo(); String issuer = payload.getAsJsonPrimitive("iss").getAsString(); String userIdString = payload.getAsJsonObject("info").getAsJsonPrimitive("user").getAsString(); User user = gson.fromJson(userIdString, User.class); Long expireDate = payload.getAsJsonPrimitive("exp").getAsLong(); if (issuer.equals(ISSUER) && (userIdString != null)) { t.setUser(user); t.setExpires(getDateTimeFromTimestamp(expireDate)); return t; } else { return null; } } catch (InvalidKeyException e1) { throw new RuntimeException(e1); } } public static LocalDateTime getDateTimeFromTimestamp(long timestamp) { if (timestamp == 0) { return null; } return LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), TimeZone.getDefault().toZoneId()); } }