Java tutorial
/* * Copyright 2014 by SCSK Corporation. * * This file is part of PrimeCloud Controller(TM). * * PrimeCloud Controller(TM) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * PrimeCloud Controller(TM) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PrimeCloud Controller(TM). If not, see <http://www.gnu.org/licenses/>. */ package jp.primecloud.auto.api; import java.io.UnsupportedEncodingException; import java.net.URI; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.LinkedHashMap; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; import jp.primecloud.auto.common.log.LoggingUtils; import jp.primecloud.auto.config.Config; import jp.primecloud.auto.entity.crud.ApiCertificate; import jp.primecloud.auto.entity.crud.Farm; import jp.primecloud.auto.entity.crud.User; import jp.primecloud.auto.exception.AutoApplicationException; import jp.primecloud.auto.exception.AutoException; import jp.primecloud.auto.util.MessageUtils; import com.sun.jersey.spi.container.ContainerRequest; import com.sun.jersey.spi.container.ContainerRequestFilter; public class ApiFilter extends ApiSupport implements ContainerRequestFilter { // private static final String AUTO_SCALING_USER = Config.getProperty("autoScaling.username"); //??????API?? private static final String[] notUseFarmApies = { "CreateFarm", "ListFarm", "Login", "ListTemplate", "ListEventLog" }; private static final Integer SECURE_WAIT_TIME = Integer.parseInt(Config.getProperty("pccApi.secureWaitTime")); /** * PCC-API ? * * ?????? * notUseFarmApies?API?????? * ???????????????? * (????????API???) * {@inheritDoc} */ public ContainerRequest filter(ContainerRequest request) { try { // URI() URI uri = request.getRequestUri(); // BASE64???URI(LinkedHashMap)?? LinkedHashMap<String, String> decodeParamMap = getDecodedParamMap(uri); String apiName = uri.getPath().substring(request.getBaseUri().getPath().length()); if (StringUtils.isEmpty(apiName)) { //API?????? throw new AutoApplicationException("EAPI-000008", "URL", uri.toString()); } //String userName = decodeParamMap.get(PARAM_NAME_KEY); String accessId = decodeParamMap.get(PARAM_NAME_ACCESS_ID); String signature = decodeParamMap.get(PARAM_NAME_SIGNATURE); String timestamp = decodeParamMap.get(PARAM_NAME_TIMESTAMP); String farmNo = decodeParamMap.get(PARAM_NAME_FARM_NO); String userName = null; Long userNo = null; Farm farm = null; User accessUser = null; User autoScaleUser = null; User masterUser = null; // ? // Key(??) ApiValidate.validateAccessId(accessId); // Signature ApiValidate.validateSignature(signature); // Timestamp(yyyy/MM/dd HH:mm:ss) ApiValidate.validateTimestamp(timestamp); // PCC-API?? ApiCertificate apiCertificate = apiCertificateDao.readByApiAccessId(accessId); if (apiCertificate == null) { // PCC-API????? Thread.sleep(SECURE_WAIT_TIME.intValue() * 1000); throw new AutoApplicationException("EAPI-000008", PARAM_NAME_ACCESS_ID, accessId); } //(API)? accessUser = userDao.read(apiCertificate.getUserNo()); if (accessUser == null) { // ???? throw new AutoApplicationException("EAPI-100000", "User", "UserNo", apiCertificate.getUserNo()); } //TODO ???? //????/?? //?????????????? //if (?) { // ? //} // Signature?? String uriText = createUriQueryParams(decodeParamMap, uri); String encodeUriText = encodeSHA256(uriText, apiCertificate.getApiSecretKey()); if (BooleanUtils.isFalse(encodeUriText.equals(signature))) { //Signature?????? Thread.sleep(SECURE_WAIT_TIME.intValue() * 1000); throw new AutoApplicationException("EAPI-000008", "URL", uri.toString()); } if (Arrays.asList(notUseFarmApies).contains(apiName) == false) { //FarmNo ApiValidate.validateFarmNo(farmNo); farm = farmDao.read(Long.parseLong(farmNo)); if (farm == null) { // ???? throw new AutoApplicationException("EAPI-100000", "Farm", PARAM_NAME_FARM_NO, farmNo); } } //????? if (farm != null && (StringUtils.isNotEmpty(AUTO_SCALING_USER) && AUTO_SCALING_USER.equals(accessUser.getUsername()) || accessUser.getPowerUser())) { //????POWER USER???? //???????????? //TODO ?????PCC-API????? autoScaleUser = userDao.read(farm.getUserNo()); userNo = autoScaleUser.getUserNo(); userName = autoScaleUser.getUsername(); } else if (!accessUser.getPowerUser() && accessUser.getUserNo().equals(accessUser.getMasterUser()) == false) { //?PCC ????? if (accessUser.getMasterUser() != null) { userNo = accessUser.getMasterUser(); masterUser = userDao.read(accessUser.getMasterUser()); userName = masterUser.getUsername(); } } else { // ????? userNo = accessUser.getUserNo(); userName = accessUser.getUsername(); } if (farm != null && farm.getUserNo().equals(userNo) == false) { // ????????? throw new AutoApplicationException("EAPI-100026", farmNo, accessUser.getUsername()); } //User(??)URL? if (!apiName.equals("Login")) { decodeParamMap.put(PARAM_NAME_USER, userName); } //LoggingUtils? LoggingUtils.setUserNo(userNo); LoggingUtils.setLoginUserNo(accessUser.getUserNo()); LoggingUtils.setUserName(accessUser.getUsername()); if (farm != null) { LoggingUtils.setFarmNo(farm.getFarmNo()); LoggingUtils.setFarmName(farm.getFarmName()); } // ??URL? for (String key : decodeParamMap.keySet()) { request.getQueryParameters().putSingle(key, decodeParamMap.get(key)); } // log.info(MessageUtils.getMessage("IAPI-000001", accessUser.getUsername(), apiName)); } catch (Throwable e) { String message = ""; if (e instanceof AutoException || e instanceof AutoApplicationException) { message = e.getMessage(); } else { message = MessageUtils.getMessage("EAPI-000000"); } // log.error(message, e); // ErrorApi? URI errorUri = URI.create(request.getBaseUri() + "Error"); request.setUris(request.getBaseUri(), errorUri); request.getQueryParameters().putSingle("Message", message); } return request; } /** * * BASE64??LinkedHashMap?? * ?BASE64 * * @param url URL * @return LinkedHashMap<??, > * @throws UnsupportedEncodingException */ @SuppressWarnings("static-access") private LinkedHashMap<String, String> getDecodedParamMap(URI uri) throws UnsupportedEncodingException { LinkedHashMap<String, String> map = new LinkedHashMap<String, String>(); String queryUrlText = uri.getQuery(); if (StringUtils.isNotEmpty(queryUrlText)) { try { Base64 base64 = new Base64(true); String decodedUri = new String(base64.decodeBase64(queryUrlText.getBytes("UTF-8")), "UTF-8"); for (String param : decodedUri.split("&")) { String key = param.substring(0, param.indexOf("=")); String value = param.substring(param.indexOf("=") + 1, param.length()); if (PARAM_NAME_SIGNATURE.equals(key)) { map.put(key, value); } else { map.put(key, value); } } } catch (Exception e) { throw new AutoApplicationException("EAPI-000008", e, "URL", uri.toString()); } } return map; } /** * * HMAC-SHA256??? * * @param plainText ? * @param keyText * @return * @throws InvalidKeyException * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException */ private static String encodeSHA256(String plainText, String keyText) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException { SecretKey secretKey = new SecretKeySpec(keyText.getBytes("UTF-8"), "HmacSHA256"); Mac mac = Mac.getInstance("HmacSHA256"); mac.init(secretKey); byte[] plainBytes = plainText.getBytes("UTF-8"); byte[] encodedBytes = mac.doFinal(plainBytes); byte[] hexBytes = new Hex().encode(encodedBytes); return new String(hexBytes, "UTF-8"); } /** * * URI(Signature????)? * * @param decodeParamMap base64?? * @param uri URI() * @return ???URL(Signature????) */ private String createUriQueryParams(LinkedHashMap<String, String> decodeParamMap, URI uri) { String baseUriText = uri.getScheme() + "://" + uri.getAuthority() + uri.getPath() + "?"; StringBuffer uriText = new StringBuffer(baseUriText); String splitChar = ""; for (String key : decodeParamMap.keySet()) { if (PARAM_NAME_SIGNATURE.equals(key) == false) { uriText.append(splitChar + key + "=" + decodeParamMap.get(key)); splitChar = "&"; } } return uriText.toString(); } // /** // * // * ??? // * // * @param encryptPass ???PCC // * @param key ??? // * @return ???PCC // */ // private String decryptUserPassword(String encryptPass, String key) { // PasswordEncryptor encryptor = new PasswordEncryptor(); // String decryptPass; // try { // decryptPass = encryptor.decrypt(encryptPass, key); // } catch(Throwable e) { // throw new AutoApplicationException("EAPI-000010", e, "Password"); // } // return decryptPass; // } }