package open.dolphin.adm20.mbean; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.SignatureException; import java.security.interfaces.RSAPrivateKey; import java.security.spec.EncodedKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Calendar; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.ejb.Singleton; import javax.ejb.Startup; import net.oauth.jsontoken.JsonToken; import net.oauth.jsontoken.crypto.RsaSHA256Signer; import org.joda.time.Instant; /** * * @author kazushi minagawa */ @Singleton @Startup public class IdentityService { private static final long TWO_MINUTES_IN_MILLISECONDS = 1000L * 60L * 2L; private LayerConfig layerConfig; @PostConstruct public void init() { layerConfig = new LayerConfig(); } @PreDestroy public void stop() { } public String getIdentityToken(String nonce, String userId) { try { final Calendar cal = Calendar.getInstance(); final RsaSHA256Signer signer = new RsaSHA256Signer(null, null, getPrivateKey()); final JsonToken token = new JsonToken(signer); final com.google.gson.JsonObject header = token.getHeader(); header.addProperty("typ", "JWT"); header.addProperty("alg", "RS256"); header.addProperty("cty", "layer-eit;v=1"); header.addProperty("kid", layerConfig.getLayerKeyId()); token.setParam("iss", layerConfig.getProviderId()); token.setParam("prn", userId); token.setIssuedAt(new Instant(cal.getTimeInMillis())); token.setExpiration(new Instant(cal.getTimeInMillis() + TWO_MINUTES_IN_MILLISECONDS)); token.setParam("nce", nonce); String ret = token.serializeAndSign(); Logger.getLogger(this.getClass().getName()).log(Level.INFO, "token={0}", ret); return ret; } catch (NoSuchAlgorithmException | InvalidKeySpecException | IOException | InvalidKeyException | SignatureException ex) { Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex); } return null; } private byte[] readPrivateKeyFromDisk(final String path) throws IOException { final File privateKeyFile = new File(path); final FileInputStream fileInputStream = new FileInputStream(privateKeyFile); final DataInputStream dis = new DataInputStream(fileInputStream); final byte[] privateBytes = new byte[(int) privateKeyFile.length()]; try { dis.readFully(privateBytes); } catch (IOException ioe) { /** No-op **/ } finally { fileInputStream.close(); } return privateBytes; } private RSAPrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException { final KeyFactory keyFactory = KeyFactory.getInstance("RSA"); final byte[] encodedKey = readPrivateKeyFromDisk(layerConfig.getRsaKeyPath()); final EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey); final PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); return (RSAPrivateKey) privateKey; } }