/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JFUiDANinsho
*   ソースファイル名：JFUiDANinsho.java
*   作成者          ：富士通
*   日付            ：2016年10月04日
*＜機能概要＞
* iDA認証部品です。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v28.00.00   2016/10/04   FJ) 横山   【ANK-3032-00-00】AxM再構築対応
*   v28.00.01   2016/11/24   FJ) 横山   【ANK-3032-03-00】AxM再構築対応【案件内仕変3:フロントからアクセスするCMPログイン画面URLの変更対応】
*
**********************************************************************/

package eo.web.webview.common;

import static com.fujitsu.futurity.web.x31.X31SWebLog.DEBUG_LOG;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import com.fujitsu.futurity.common.JSYLogBase;
import com.fujitsu.futurity.common.JSYwebLog;
import com.fujitsu.futurity.web.x33.HttpDispatchContext;
import com.fujitsu.futurity.web.x33.X33CUtil;
import com.fujitsu.futurity.web.x33.X33WSessionController;

import eo.common.constant.JFUStrConst;
import eo.common.util.JCCFrameworkException;
import eo.common.util.JFUCommonUtil;
import eo.web.webview.JCCWebBusinessLogic;

import org.apache.commons.codec.binary.Base64;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * 
 * <br>
 * @author 富士通
 */
public class JFUiDANinsho extends JFUUrlConnection
{

	/** iDA認証ＫＥＹ 共通 */
	/** iDA認証 KEY名 */
	private static final String RCEIVE_DATA = "receiveData";

	/** iDA認証ＫＥＹ_連携先システムコード */
	private static final String COOPERATION_SYSTEM_CODE = "COOPERATION_SYSTEM_CODE";

	/** iDA認証ＫＥＹ_体系ＩＤ */
	private static final String ORG_ID = "ORG_ID";

	/** iDA認証ＫＥＹ_属性リスト要否 */
	private static final String NEED_PROPERTY_LIST = "NEED_PROPERTY_LIST";

	/** iDA認証ＫＥＹ iDA認証送信処理 */
	/** iDA認証ＫＥＹ_ログインＩＤ */
	private static final String LOGIN_ID = "LOGIN_ID";

	/** iDA認証ＫＥＹ_ログインパスワード */
	private static final String LOGIN_PASSWORD = "LOGIN_PASSWORD";

	/** iDA認証ＫＥＹ_認証段階 */
	private static final String AUTH_STEP = "AUTH_STEP";

	/** iDA認証ＫＥＹ_クライアントＩＰ */
	private static final String CLIENT_IP = "CLIENT_IP";

	/** iDA認証ＫＥＹ_SSOToken要否 */
	private static final String NEED_SSO_TOKEN = "NEED_SSO_TOKEN";

	/** iDA認証ＫＥＹ_SITE_サイト識別用文字列 */
	private static final String SITE_IDENTIFIER = "SITE_IDENTIFIER";

	/** iDA認証ＫＥＹ iDA認証確認送信処理 */
	/** iDA認証ＫＥＹ_SSOToken */
	private static final String SSO_TOKEN = "SSO_TOKEN";

	/** iDA認証ＫＥＹ_Token更新要否 */
	private static final String NEED_UPDATE_TOKEN = "NEED_UPDATE_TOKEN";

	/** iDA認証ＫＥＹ_セッション情報要否 */
	private static final String NEED_SESSION_INFO = "NEED_SESSION_INFO";

	/** iDA認証取得ＫＥＹ_戻り値  */
	private static final String IDA_RETURN_CODE = "RETURN_CODE";

	/** iDA認証取得ＫＥＹ_ユーザ属性  */
	private static final String IDA_USER_PROPERTIES = "USER_PROPERTIES";

	/** iDA認証取得ＫＥＹ_会員種別 */
	private static final String IDA_KIIN_SHUBT = "kiin_shubt";

	/** iDA認証取得ＫＥＹ_SYSID  */
	private static final String IDA_SYSID = "sysid";

	/** iDA認証取得ＫＥＹ登録フラグ  */
	private static final String IDA_TURK_FLG = "turk_flg";

	/** iDA認証取得ＫＥＹ_ssoToken  */
	private static final String IDA_SSOTOKEN = "SSOToken";

	/** iDA認証 返却用キー */
	/** 返却値の状態設定用キー */
	private static final String RETURN_RETURN_CODE = "RETURN_CODE";

	/** 返却値のSYSID設定用キー */
	private static final String RETURN_SYSID = "SYSID";

	/** 返却値の会員種別設定用キー */
	private static final String RETURN_KIIN_SHUBT = "KIIN_SHUBT";

	/** 返却値の登録フラグ */
	private static final String RETURN_TURK_FLG = "TURK_FLG";

	/** 返却値のSSOTOKEN */
	private static final String RETURN_SSO_TOKEN = "SSO_TOKEN";

	/** Basic認証文字列 */
	private static final String BASIC_AUTH = "Authorization";

	/** 文字列 コロン */
	private static final String BASIC_AND_SPACE = "Basic ";

	/** TESTMODE用項目 */
	/** 登録フラグ */
	private static final String DUMMY_TURK_FLG = "1";

	/** 文字列：TESTMODE */
	private static final String TEST_TESTMODE = "TESTMODE";

	/** 文字列：SYSID */
	private static final String TEST_SYSID = "SYSID";

	/** 文字列：= */
	private static final String TEST_EQUAL = "=";

	/**
	 *iDA側の認証APIの呼び出し処理を要求し結果を返却します。
	 * <br>
	 * @param vlObj Viewロジックインスタンス
	 * @param loginId ログインＩＤ
	 * @param loginPassword ログインパスワード
	 * @param clientIp クライアントＩＰ
	 * @param isCreateCookieFlg クッキー情報生成フラグ
	 * @param beforeSysid 前回認証処理のSSO情報から取得したSYSID
	 * @param sessionCreList セッション作成対象リスト
	 * @return 結果
	 * @throws Exception
	 */
	public static HashMap<String, String> authenticateApi(JCCWebBusinessLogic vlObj, String loginId, String loginPassword, String clientIp,
			boolean isCreateCookieFlg, String beforeSysid, List sessionCreList) throws Exception
	{
		// パラメータチェック
		// Viewロジックインスタンスのチェック
		if (null == vlObj)
		{
			throw new JCCFrameworkException("引数のViewロジックインスタンスがnullです。");
		}

		// 結果返却用マップ
		HashMap<String, String> resultMap = new HashMap<String, String>();

		// ログインIDのチェック
		if (JFUWebCommon.isNull(loginId))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_NO_REQ);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}
		// ログインパスワードのチェック
		if (JFUWebCommon.isNull(loginPassword))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_NO_REQ);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}
		// クライアントＩＰのチェック
		if (JFUWebCommon.isNull(clientIp))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_NO_REQ);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}
		// クッキー情報生成フラグのチェック
		if (JFUWebCommon.isNull(isCreateCookieFlg))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_NO_REQ);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 外部未接続時の処理
		String idaConect = JCCWebCommon.getApplicationConst(JFUStrConst.IDA_CONNECTION);
		if (!JFUStrConst.ON.equals(idaConect))
		{
			return getAuthenticateApiTest(vlObj, loginId, loginPassword, clientIp, isCreateCookieFlg, beforeSysid, sessionCreList);
		}

		HttpURLConnection conn = null;
		// iDA認証処理
		try
		{
			// アプリケーションプロパティファイルより情報を取得する。
			// タイムアウト時間取得
			int timeOutValue = Integer.parseInt(JCCWebCommon.getApplicationConst(JFUStrConst.IDA_NINSHO_TIMEOUT_KEY));

			// 接続情報生成
			conn = createConnection(JFUStrConst.IDA_NINSHO_URL_KEY, timeOutValue);

			String accountNm = JCCWebCommon.getApplicationConst(JFUStrConst.FU_IDA_AUTH_ACCOUNT_KEY);
			String password = JCCWebCommon.getApplicationConst(JFUStrConst.FU_IDA_AUTH_PASSWORD_KEY);

			if (!(JFUWebCommon.isNull(accountNm) || JFUWebCommon.isNull(password)))
			{
				//Basic認証文字列を設定する。
				conn.setRequestProperty(BASIC_AUTH, makeBasicAuth(accountNm, password));
			}

			// 設定情報の格納
			JSONObject setteInfo = new JSONObject();

			// アプリケーションプロパティファイルより取得した情報、連携値を設定する。
			// 連携先システムコード
			setteInfo.put(COOPERATION_SYSTEM_CODE, JCCWebCommon.getApplicationConst(JFUStrConst.IDA_CFM_COOPERATION_SYS_CD));
			// 体系ＩＤ
			setteInfo.put(ORG_ID, JCCWebCommon.getApplicationConst(JFUStrConst.IDA_ORG_ID));
			// ログインＩＤ
			setteInfo.put(LOGIN_ID, loginId);
			// ログインパスワード
			setteInfo.put(LOGIN_PASSWORD, loginPassword);
			// 認証段階
			setteInfo.put(AUTH_STEP, JCCWebCommon.getApplicationConst(JFUStrConst.IDA_AUTH_STEP));
			// クライアントＩＰ
			setteInfo.put(CLIENT_IP, clientIp);
			// 属性リスト要否
			setteInfo.put(NEED_PROPERTY_LIST, JCCWebCommon.getApplicationConst(JFUStrConst.IDA_NEED_PROPERTY_LIST));
			// SSOToken要否
			setteInfo.put(NEED_SSO_TOKEN, JCCWebCommon.getApplicationConst(JFUStrConst.IDA_NEED_SSO_TOKEN));

			// ドメイン取得
			String idaDomain = JCCWebCommon.getApplicationConst(JFUStrConst.IDA_NINSHO_DOMAIN);
			// サイト識別用文字列
			setteInfo.put(SITE_IDENTIFIER, idaDomain);

			// 認証処理
			outputBusLog("iDA認証：LOGIN_ID=" + loginId, vlObj.getClass());
			DEBUG_LOG.info("DEBUG：iDA認証接続 start");
			DEBUG_LOG.info("DEBUG：iDA認証処理 in項目=" + setteInfo.toString());

			// 文字コード取得
			String encode = JCCWebCommon.getApplicationConst(JFUStrConst.IDA_NINSHO_ENCODE);
			conn = connection(conn, RCEIVE_DATA, setteInfo.toString(), encode);
			// 認証結果の取得
			BufferedInputStream bis = null;
			ByteArrayOutputStream bos = null;
			byte[] outputByte = null;
			try
			{
				bis = new BufferedInputStream(conn.getInputStream());
				// レスポンスを読込み
				bos = new ByteArrayOutputStream();
				int intByte = 0;
				while (true)
				{
					intByte = bis.read();
					if (-1 == intByte)
					{
						break;
					}
					bos.write(intByte);
				}
				outputByte = bos.toByteArray();
			}
			finally
			{
				if (null != bos)
				{
					bos.close();
				}
				if (null != bis)
				{
					bis.close();
				}
			}
			String ninshoKekka = new String(outputByte, encode);

			JSONObject rceiveObject = new JSONObject(ninshoKekka);
			DEBUG_LOG.info("DEBUG：iDA認証処理 out項目=" + rceiveObject.toString());

			String rcvRtnCd = rceiveObject.getString(IDA_RETURN_CODE);
			resultMap.put(RETURN_RETURN_CODE, rcvRtnCd);
			if (JFUStrConst.IDA_NINSHO_CD_OK.equals(rcvRtnCd))
			{
				JSONObject rceiveUserObject = new JSONObject(rceiveObject.getString(IDA_USER_PROPERTIES));
				String rcvSysid = rceiveUserObject.getString(IDA_SYSID);
				if (!JFUCommonUtil.isNull(rcvSysid))
				{
					resultMap.put(RETURN_SYSID, rcvSysid);
				}
				else
				{
					resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
				}
				String rcvKiinSbtCd = rceiveUserObject.getString(IDA_KIIN_SHUBT);
				if (!JFUCommonUtil.isNull(rcvKiinSbtCd))
				{
					resultMap.put(RETURN_KIIN_SHUBT, rcvKiinSbtCd);
				}
				else
				{
					resultMap.put(RETURN_KIIN_SHUBT, JFUStrConst.EMPTY);
				}
				String rcvTurkFlg = rceiveUserObject.getString(IDA_TURK_FLG);
				if (!JFUCommonUtil.isNull(rcvTurkFlg))
				{
					resultMap.put(RETURN_TURK_FLG, rcvTurkFlg);
				}
				else
				{
					resultMap.put(RETURN_TURK_FLG, JFUStrConst.EMPTY);
				}
				// クッキー情報生成
				String ssoToken = rceiveObject.getString(IDA_SSOTOKEN);
				if (!JFUCommonUtil.isNull(ssoToken))
				{
					resultMap.put(RETURN_SSO_TOKEN, ssoToken);
					// クッキー作成対象リストが渡されている場合
					if (sessionCreList != null)
					{
						if (isCreateCookieFlg && sessionCreList.contains(rcvKiinSbtCd)
								&& (JFUCommonUtil.isNull(beforeSysid) || rcvSysid.equals(beforeSysid)))
						{
							// 認証成功時の処理
							String sessionId = vlObj.getSession().getViewParamId().getSessionID();
							// クッキー情報生成処理
							createSmCookie(sessionId, ssoToken);
						}
					}
				}
				else
				{
					resultMap.put(RETURN_SSO_TOKEN, JFUStrConst.EMPTY);
				}
				outputBusLog("iDA認証：LOGIN_ID=" + loginId + "：ステータス=" + rcvRtnCd + "：SYSID=" + rcvSysid, vlObj.getClass());
			}
			else
			{
				resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
				outputBusLog("iDA認証：LOGIN_ID=" + loginId + "：ステータス=" + rcvRtnCd, vlObj.getClass());
			}
		}
		catch (NoSuchAlgorithmException ne)
		{
			outputBusLog("iDA認証接続エラー NoSuchAlgorithmException", vlObj.getClass());
			JCCFrameworkException fe = new JCCFrameworkException();
			fe.initCause(ne);
			throw fe;
		}
		catch (KeyManagementException ke)
		{
			outputBusLog("iDA認証接続エラー KeyManagementException", vlObj.getClass());
			JCCFrameworkException fe = new JCCFrameworkException();
			fe.initCause(ke);
			throw fe;
		}
		catch (IOException ie)
		{
			outputBusLog("iDA認証接続エラー IOException", vlObj.getClass());
			JCCFrameworkException fe = new JCCFrameworkException();
			fe.initCause(ie);
			throw fe;
		}
		catch (JSONException je)
		{
			outputBusLog("iDA認証接続エラー JSONException", vlObj.getClass());
			JCCFrameworkException fe = new JCCFrameworkException();
			fe.initCause(je);
			throw fe;
		}
		finally
		{
			if (null != conn)
			{
				conn.disconnect();
			}
			DEBUG_LOG.info("DEBUG：iDA認証接続 end");
		}

		return resultMap;
	}

	/**
	 * iDA側の認証確認APIの呼び出し処理を要求し結果を返却します。
	 * <br>
	 * @param ssoToken SSOToken
	 * @param vlObj Viewロジックインスタンス
	 * @return 結果
	 */
	public static HashMap<String, String> authConfirmApi(String ssoToken, JCCWebBusinessLogic vlObj)
	{
		// 結果返却用マップ
		HashMap<String, String> resultMap = new HashMap<String, String>();

		// パラメータチェック
		// Viewロジックインスタンスのチェック
		if (null == vlObj)
		{
			throw new JCCFrameworkException("引数のViewロジックインスタンスがnullです。");
		}

		// ssoTokenのチェック
		if (JFUWebCommon.isNull(ssoToken))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_NG);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 外部未接続時の処理
		String idaConect = JCCWebCommon.getApplicationConst(JFUStrConst.IDA_CONNECTION);
		if (!JFUStrConst.ON.equals(idaConect))
		{
			return getAuthConfirmApiTest(ssoToken, vlObj);
		}

		HttpURLConnection conn = null;
		// iDA認証確認処理
		try
		{
			// アプリケーションプロパティファイルより情報を取得する。
			// タイムアウト時間取得
			int timeOutValue = Integer.parseInt(JCCWebCommon.getApplicationConst(JFUStrConst.IDA_NINSHO_CONF_TIMEOUT_KEY));

			// 接続情報生成
			conn = createConnection(JFUStrConst.IDA_NINSHO_CONF_URL_KEY, timeOutValue);

			String accountNm = JCCWebCommon.getApplicationConst(JFUStrConst.FU_IDA_AUTH_CONF_ACCOUNT_KEY);
			String password = JCCWebCommon.getApplicationConst(JFUStrConst.FU_IDA_AUTH_CONF_PASSWORD_KEY);

			if (!(JFUWebCommon.isNull(accountNm) || JFUWebCommon.isNull(password)))
			{
				//Basic認証文字列を設定する。
				conn.setRequestProperty(BASIC_AUTH, makeBasicAuth(accountNm, password));
			}

			// 設定情報の格納
			JSONObject setteInfo = new JSONObject();

			// アプリケーションプロパティファイルより取得した情報、連携値を設定する。
			// 連携先システムコード
			setteInfo.put(COOPERATION_SYSTEM_CODE, JCCWebCommon.getApplicationConst(JFUStrConst.IDA_CFM_COOPERATION_SYS_CD));
			// 体系ＩＤ
			setteInfo.put(ORG_ID, JCCWebCommon.getApplicationConst(JFUStrConst.IDA_CFM_ORG_ID));
			// SSOToken
			setteInfo.put(SSO_TOKEN, ssoToken);
			// Token更新要否
			setteInfo.put(NEED_UPDATE_TOKEN, JCCWebCommon.getApplicationConst(JFUStrConst.IDA_CFM_NEED_UPD_TKE));
			// セッション情報要否
			setteInfo.put(NEED_SESSION_INFO, JCCWebCommon.getApplicationConst(JFUStrConst.IDA_CFM_NEED_SESSION_INFO));
			// 属性リスト要否
			setteInfo.put(NEED_PROPERTY_LIST, JCCWebCommon.getApplicationConst(JFUStrConst.IDA_CFM_NEED_PROPERTY_LIST));

			// 認証処理
			outputBusLog("iDA認証確認：SSOToken=" + ssoToken, vlObj.getClass());
			DEBUG_LOG.info("DEBUG：iDA認証確認接続 start");
			DEBUG_LOG.info("DEBUG：iDA認証確認処理 in項目=" + setteInfo.toString());

			// 文字コード取得
			String encode = JCCWebCommon.getApplicationConst(JFUStrConst.IDA_NINSHO_CONF_ENCODE);

			conn = connection(conn, RCEIVE_DATA, setteInfo.toString(), encode);
			// 認証結果の取得
			BufferedInputStream bis = null;
			ByteArrayOutputStream bos = null;
			byte[] outputByte = null;
			try
			{
				bis = new BufferedInputStream(conn.getInputStream());
				// レスポンスを読込み
				bos = new ByteArrayOutputStream();
				int intByte = 0;
				while (true)
				{
					intByte = bis.read();
					if (-1 == intByte)
					{
						break;
					}
					bos.write(intByte);
				}
				outputByte = bos.toByteArray();
			}
			finally
			{
				if (null != bos)
				{
					bos.close();
				}
				if (null != bis)
				{
					bis.close();
				}
			}
			String ninshoKekka = new String(outputByte, encode);

			JSONObject rceiveObject = new JSONObject(ninshoKekka);
			DEBUG_LOG.info("DEBUG：iDA認証確認処理 out項目=" + rceiveObject.toString());

			String rcvRtnCd = rceiveObject.getString(IDA_RETURN_CODE);
			resultMap.put(RETURN_RETURN_CODE, rcvRtnCd);
			String rcvSysid = JFUStrConst.EMPTY;
			if (JFUStrConst.IDA_NINSHO_CD_OK.equals(rcvRtnCd))
			{
				JSONObject rceiveUserObject = new JSONObject(rceiveObject.getString(IDA_USER_PROPERTIES));
				rcvSysid = rceiveUserObject.getString(IDA_SYSID);
				if (!JFUCommonUtil.isNull(rcvSysid))
				{
					resultMap.put(RETURN_SYSID, rcvSysid);
				}
				else
				{
					resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
				}
			}
			else
			{
				resultMap.put(RETURN_SYSID, rcvSysid);
			}
			outputBusLog("iDA認証確認：SSOToken=" + ssoToken + "：ステータス=" + rcvRtnCd + "：SYSID=" + rcvSysid, vlObj.getClass());
		}
		catch (NoSuchAlgorithmException ne)
		{
			outputBusLog("iDA認証確認接続エラー NoSuchAlgorithmException", vlObj.getClass());
			JCCFrameworkException fe = new JCCFrameworkException();
			fe.initCause(ne);
			throw fe;
		}
		catch (KeyManagementException ke)
		{
			outputBusLog("iDA認証確認接続エラー KeyManagementException", vlObj.getClass());
			JCCFrameworkException fe = new JCCFrameworkException();
			fe.initCause(ke);
			throw fe;
		}
		catch (IOException ie)
		{
			outputBusLog("iDA認証確認接続エラー IOException", vlObj.getClass());
			JCCFrameworkException fe = new JCCFrameworkException();
			fe.initCause(ie);
			throw fe;
		}
		catch (JSONException je)
		{
			outputBusLog("iDA認証確認接続エラー JSONException", vlObj.getClass());
			JCCFrameworkException fe = new JCCFrameworkException();
			fe.initCause(je);
			throw fe;
		}
		finally
		{
			if (null != conn)
			{
				conn.disconnect();
			}
			DEBUG_LOG.info("DEBUG：iDA認証確認接続 end");
		}

		return resultMap;
	}

	/**
	 * Cookie(SMSESSION)の生成処理を行う
	 * <br>
	 * @param sessionId Viewロジックインスタンス
	 * @param ssoToken ssoToken
	 */
	private static void createSmCookie(String sessionId, String ssoToken)
	{
		DEBUG_LOG.info("DEBUG：Cookie情報(SMSESSION)生成処理 start");
		// Cookieオブジェクトの生成
		Cookie cookie = new Cookie(JFUStrConst.IDA_NINSHO_COOKIES_KEY, ssoToken);

		// アプリケーションプロパティファイルよりCookieの有効ドメインを取得する。
		String idaCookieDomain = JCCWebCommon.getApplicationConst(JFUStrConst.KEY_IDA_COOKIE_DOMAIN);
		// アプリケーションプロパティファイルの必須チェック
		if (idaCookieDomain == null)
		{
			throw new JCCFrameworkException("APLConst.propertiesにIDA_COOKIE_DOMAINが設定されていません。");
		}
		// Cookieへ属性を設定する。
		cookie.setDomain(idaCookieDomain); // Cookieの有効ドメインを設定
		// アプリケーションプロパティファイルよりCookieの有効パスを取得する。
		String idaCookiePath = JCCWebCommon.getApplicationConst(JFUStrConst.KEY_IDA_COOKIE_PATH);
		// アプリケーションプロパティファイルの必須チェック
		if (idaCookiePath == null)
		{
			throw new JCCFrameworkException("APLConst.propertiesにIDA_COOKIE_PATHが設定されていません。");
		}
		// Cookieへ属性を設定する。
		cookie.setPath(idaCookiePath); // Cookieの有効パスを設定
		// アプリケーションプロパティファイルよりCookieの最長存続期間を取得する。
		String idaCookieAge = JCCWebCommon.getApplicationConst(JFUStrConst.KEY_IDA_COOKIE_AGE);
		// アプリケーションプロパティファイルの必須チェック
		if (idaCookieAge == null)
		{
			throw new JCCFrameworkException("APLConst.propertiesにIDA_COOKIE_AGEEが設定されていません。");
		}
		// Cookieへ属性を設定する。
		cookie.setMaxAge(Integer.parseInt(idaCookieAge)); // Cookieの最長存続期間を設定
		// アプリケーションプロパティファイルよりCookieのsecure属性を取得する。
		String idaCookieSecure = JCCWebCommon.getApplicationConst(JFUStrConst.KEYIDA_COOKIE_SECURE);
		// アプリケーションプロパティファイルの必須チェック
		if (idaCookieSecure == null)
		{
			throw new JCCFrameworkException("APLConst.propertiesにIDA_COOKIE_SECUREが設定されていません。");
		}
		// Cookieへ属性を設定する。
		cookie.setSecure(Boolean.parseBoolean(idaCookieSecure)); // Cookieのsecure属性を設定

		// HttpServletResponseオブジェクトの取得
		X33WSessionController sc = X33CUtil.getSession(sessionId);
		HttpServletResponse res = ((HttpDispatchContext)sc.getContext()).getServletResponse();
		// Cookieのセット
		res.addCookie(cookie);

		DEBUG_LOG.info("DEBUG：Cookie情報(SMSESSION)生成処理 end");
	}

	/**
	 * ビジネスログへの出力処理
	 *
	 * @param msg ログ情報
	 * @param cls クラス
	 */
	@SuppressWarnings("unchecked")
	public static void outputBusLog(String msg, Class cls)
	{
		JSYwebLog.println(JSYLogBase.EXECUTION, cls, msg, "CS0003I", null, null);
	}

	/**
	 * テストモードでの認証処理
	 * <br>
	 * ユーザーIDにより返却値が変わる
	 * @param vlObj Viewロジックインスタンス
	 * @param loginId ログインＩＤ
	 * @param loginPassword ログインパスワード
	 * @param clientIp クライアントＩＰ
	 * @param isCreateCookieFlg クッキー情報生成フラグ
	 * @param beforeSysid 前回認証処理のSSO情報から取得したSYSID
	 * @param sessionCreList セッション作成対象リスト
	 * @return テストモードでの認証結果
	 * @throws Exception
	 */
	private static HashMap<String, String> getAuthenticateApiTest(JCCWebBusinessLogic vlObj, String loginId, String loginPassword, String clientIp,
			boolean isCreateCookieFlg, String beforeSysid, List sessionCreList) throws Exception
	{
		// 結果返却用マップ
		HashMap<String, String> resultMap = new HashMap<String, String>();

		//ユーザーが存在しないときの設定
		resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_NO_REQ);
		resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);

		// ユーザーIDが4ケタ以上あるかどうかの確認
		if (!(loginId.length() >= 4))
		{
			return resultMap;
		}

		// 先頭がTどうかの確認
		if (!"T".equals(loginId.substring(0, 1)))
		{
			return resultMap;
		}

		// 2桁目〜4桁目が整数値として扱えない場合
		String id2to4 = loginId.substring(1, 4);
		int num = 0;
		if (id2to4.matches("[0-9][0-9][0-9]"))
		{
			num = Integer.parseInt(id2to4);
		}
		else
		{
			return resultMap;
		}

		// 認証成功のユーザーID
		if ((num >= 0) && (num <= 9))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_OK);
			resultMap.put(RETURN_SYSID, loginPassword);
			resultMap.put(RETURN_TURK_FLG, DUMMY_TURK_FLG);

			if (num == 6)
			{
				resultMap.put(RETURN_KIIN_SHUBT, JFUStrConst.CD00039_11);
			}
			else if (num == 7)
			{
				resultMap.put(RETURN_KIIN_SHUBT, JFUStrConst.CD00039_20);
			}
			else if (num == 8)
			{
				resultMap.put(RETURN_KIIN_SHUBT, JFUStrConst.CD00039_21);
			}
			else if (num == 9)
			{
				resultMap.put(RETURN_KIIN_SHUBT, JFUStrConst.CD00039_30);
			}
			else
			{
				resultMap.put(RETURN_KIIN_SHUBT, JFUStrConst.CD00039_10);
			}
			String ninshoStat = JCCWebCommon.getApplicationConst(JFUStrConst.TEST_IDA_NINSHO_STAT);
			// ダミーssoToken部分を生成
			StringBuilder sb = new StringBuilder();
			sb.append(TEST_TESTMODE);
			sb.append(ninshoStat);
			sb.append(TEST_SYSID);
			sb.append(loginPassword);
			sb.append(TEST_EQUAL);
			sb.append(JCCWebCommon.getSysDateTime());
			String ssoToken = sb.toString();
			resultMap.put(RETURN_SSO_TOKEN, ssoToken);
			// クッキー作成対象リストが渡されている場合
			if (sessionCreList != null)
			{
				if (isCreateCookieFlg && sessionCreList.contains(resultMap.get(RETURN_KIIN_SHUBT))
						&& (JFUCommonUtil.isNull(beforeSysid) || loginPassword.equals(beforeSysid)))
				{
					// 以下は(テストモードのため行わない（コメントアウト）
					// 認証成功時の処理
					// String sessionId = vlObj.getSession().getViewParamId().getSessionID();
					// クッキー情報生成処理)
					// createSmCookie(sessionId, ssoToken);
				}
			}
			return resultMap;
		}

		// メンテナンスフラグが立っているケース
		else if ((num >= 10) && (num <= 19))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_SYS_MENT);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 許可されていない連携先システムコード
		else if ((num >= 20) && (num <= 29))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_RNKSK_SYSCD_ERR);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// リクエストパラメータ「receiveData」なし
		else if ((num >= 30) && (num <= 39))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_NO_REQ);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// リクエストパラメータのパース不能
		else if ((num >= 40) && (num <= 49))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_REQ_HUBI);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 単項目のバリデーションチェックＮＧ
		else if ((num >= 50) && (num <= 59))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_VARI_ERR);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// Select時にタイムアウトなど例外が発生
		else if ((num >= 60) && (num <= 69))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_GET_FAIL);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 汎用のシステムエラー
		else if ((num >= 70) && (num <= 79))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_SYS_ERR);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// CASSOの機能呼出でエラーが発生
		else if ((num >= 80) && (num <= 89))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_SYS_ERR_CASSO);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 処理対象のデータが存在しない
		else if ((num >= 90) && (num <= 99))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_NOT);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 処理対象のデータが重複
		else if ((num >= 100) && (num <= 109))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_DOUBLE);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 処理対象のユーザーが存在しない
		else if ((num >= 110) && (num <= 119))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_NO_USERT);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 処理対象のパスワードが間違っている
		else if ((num >= 120) && (num <= 129))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_PASS_ERR);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// ユーザーが手動ロックされている
		else if ((num >= 130) && (num <= 139))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_HAND_LOCK);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// ユーザーが自動ロックされている
		else if ((num >= 140) && (num <= 149))
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_AUTO_LOCK);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 業務ロジックによるその他エラー
		else
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_ETC_ERR);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

	}

	/**
	 * テストモードでの認証確認処理
	 * <br>
	 * @param ssoToken SSOToken
	 * @param vlObj Viewロジックインスタンス
	 * @return テストモードでの認証結果
	 */
	public static HashMap<String, String> getAuthConfirmApiTest(String ssoToken, JCCWebBusinessLogic vlObj)
	{
		// 結果返却用マップ
		HashMap<String, String> resultMap = new HashMap<String, String>();

		//ユーザーが存在しないときの設定
		resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_ERR);
		resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);

		// SsoTokenが25ケタ以上あるかどうかの確認
		if (!(ssoToken.length() >= 25))
		{
			return resultMap;
		}

		// TESTMODEによる分岐
		int num = 0;
		// 先頭がTESTMODEかどうかの確認
		if (!TEST_TESTMODE.equals(ssoToken.substring(0, 8)))
		{
			return resultMap;
		}

		// 9桁目〜10桁目が整数値として扱えない場合
		String id9to10 = ssoToken.substring(8, 10);
		if (id9to10.matches("[0-9][0-9]"))
		{
			num = Integer.parseInt(id9to10);
		}
		else
		{
			return resultMap;
		}

		// 汎用の正常終了（認証OKの場合）
		if (num == 0)
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_OK);
			// SSOTokenの16文字目〜25文字目
			resultMap.put(RETURN_SYSID, ssoToken.substring(15, 25));
			return resultMap;
		}

		// 正常終了の異なるパターン（認証NGの場合）
		else if (num == 1)
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_SYS_MENT);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 許可されていない連携先システムコード
		else if (num == 2)
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_RNKSK_SYSCD_ERR);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// リクエストパラメータ「receiveData」なし
		else if (num == 3)
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_NO_REQ);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// リクエストパラメータのパース不能
		else if (num == 4)
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_REQ_HUBI);
			;
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 単項目のバリデーションチェックＮＧ
		else if (num == 5)
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_VARI_ERR);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// Select時にタイムアウトなど例外が発生
		else if (num == 6)
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_GET_FAIL);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// CASSOの機能呼出でエラーが発生
		else if (num == 7)
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_SYS_ERR_CASSO);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}

		// 実行時例外などが発生
		else
		{
			resultMap.put(RETURN_RETURN_CODE, JFUStrConst.IDA_NINSHO_CD_ERR);
			resultMap.put(RETURN_SYSID, JFUStrConst.EMPTY);
			return resultMap;
		}
	}

	/**
	 * BASIC認証の文字列を作成する
	 * <br>
	 * @param accoutName アカウント名
	 * @param password パスワード
	 * @return "Basic " + [ユーザ]:[パスワード]をBASE64エンコードした文字列
	 */
	private static String makeBasicAuth(String accoutName, String password)
	{
		String userAndPasswd = accoutName + JFUStrConst.HALF_COLON + password;

		byte[] encodedBytes = Base64.encodeBase64(userAndPasswd.getBytes());

		String encodedString = new String(encodedBytes);

		return BASIC_AND_SPACE + encodedString;
	}

}
