Sử dụng tính năng xác thực 2 lần OTP của Onelogin để áp dụng vào trong dự án.

Giới thiệu tính năng xác thực 2 lần OTP của Onelogin và áp dụng vào trong dự án.

Mục tiêu : tăng cường chức năng bảo mật của các User Account. Khi Login trên PC thì cần phải mã xác thực OTP được gửi trên smartphone để xác thực

Chuẩn bị :

Vào trang chủ của Onelogin để tạo 1  Account:

https://www.onelogin.com/signup

  • ID : xxxxxxxxxxxxx@gmo.jp
  • Pass : **************

I .Thêm yếu tố chứng thực trong OneLogin (Adding your authentication factor)

Để sử dụng xác thực đa yếu tố với Onelogin , bạn phải bật một hoăc nhiều yếu tố xác thực cho tài khoản OneLogin của bạn .

1. Đăng nhập vào OneLogin với tài khoản của bạn như là một adminstrator.

2. Chọn Settings > Authentication Factors.

3. Trong trang  Authentication & Security , click New Auth Factor.

4. Chọn một trong các nhà cung cấp authentication.

      OneLogin cung cấp một số yếu tố xác thực, bao gồm OneLogin Protect, OneLogin OTP cho Windows, OneLogin OTP SMS và OneLogin Security Questions. Ngoài ra bạn cũng có thể sử dụng các yếu tố xác thực của các nhà cung cấp khác , ví dụ như  Google Authencator...

5.  Điền những thông tin cần thiết 

Có nhứng yếu tố xác thực yêu cầu bạn phải thiết lập trước .

Ví dụ :

  • OneLogin OTP SMS :  yêu cầu bạn phải đăng kí dịch vụ gửi tin nhắn của Twilio (hình như có mất phí) , sau đó nhập thông tin cần thiết trong mục    SETTINGS > Account Settings > SMS  

          https://support.onelogin.com/hc/en-us/articles/201551684-OneLogin-OTP-SMS

  • Security Question :  yêu cầu bạn phải thiết lập sẵn danh sách các câu hỏi xác thực .  Và thiết lập ơ trong mục  Settings > Authentication Factors, and go to the Security Questions 

          https://support.onelogin.com/hc/en-us/articles/202776734-Security-Questions

6.  Click Save

Sau khi bạn thêm một yếu tố xác thực mới nó sẽ xuất hiện trong trong trang Authencation & Security page.  Trong bài viết này mình thêm yếu tố xác thực của Google.

 

II . Thêm yếu tố xác thực vào trong chính sách xác thực người dùng của OneLogin (Adding the authentication factor to a user security policy)

  1. Vào Setting > Policies.
  2.  Click New User Policy
  3. Chọn tab MFA và enable OTP Auth Required.
  4. Nếu bạn đăng ký nhiều yếu tố xác thực  thì trong mục Avaliable factors sẽ xuất hiện nhiều lựa trọn , bạn có thể trọn một , hoặc nhiều cái 1 lúc cũng được.

 

 

※ Trong mục OTP bypassed for the following IP address  đây là nơi sẽ  add những địa chỉ IP mà bạn muốn bỏ qua việc check xác thực 2 lần . Ví dụ như địa chỉ IP của công ty chẳng hạn , khi bạn add IP vô đây thì khi bạn Login ở công ty nó sẽ không yêu cầu mã xác thực làm chi cho mắc công mà sẽ cho bạn Login thẳng vào ứng dụng của bạn luôn .

5. Lựa chọn các user mà sẽ yêu cầu xác thực 2 lần .(require OTP)

6. Lựa chọn khi nào thì yêu cầu xác thực 2 lần (OTP required at )

7 . Click Save .

 

III . Tạo Google Authenticator .

Bước này sẽ hướng dẫn cho bạn cách thiết lập Google Authenticator làm yếu tố xác thực cho Onelogin.

Yêu cầu : Bạn phải download ứng dụng Google Authenticator trên điện thoại của bạn .

  1. Chọn  Profile > Security.

2. Trong trang  Security   click vào dấu "+"  để add yếu tố xác thực mới , trong bài viết này mình dùng Google Authenticator

3.  Chọn Google Authentication từ trong dropdown menu.

 

4.   Dùng ứng dụng Google Authenticator của trên điện thoại của bạn Scan barcode trên màn hình .

5. Sau đó nhập mã xác thực được generated  bởi ứng dụng   Google Authenticator và click Continue.

Vậy là đã hoàn thành việc thêm yếu tố xác thực 2 lần vào rồi . Bây giờ bạn sẽ thấy nó xuất hiện  bên dưới mục  Authentication Devices  của trang security 

Test thôi 

Bấy giờ bạn Logout rồi Login vô lại nó sẽ yêu cầu bạn  nhập mã xác nhận từ ứng dụng Google Authenticator trên điện thoại 

 

 

IV . Áp dụng vào dự án thưc bằng cách sử dụng API của OneLogin .

Bạn có thể sử dụng API OneLogin để yêu cầu xác thực 2 lần khi bạn đăng nhập vào hệ thống ứng dụng của bạn . Khi bạn đặng nhập vào ứng dụng của bạn , nó sẽ yêu cầu bạn nhập mã xác thực được gửi đến điện thoại của bạn.  Xem sơ đồ bên dưới để hiểu rõ hơn về logic . Việc xử lý xác thưc Onelogin sẽ làm hết cho bạn .

1 .  Tạo cặp key  xác nhận API (Creating an API Credential Pair)

Link hướng dẫn chi tiết : https://developers.onelogin.com/api-docs/1/getting-started/working-with-api-credentials

  • Đặng nhập vào Onelogin bằng tài khoản như là account owner hoặc administrator
  • Chọn Settings > API.
  • Trong trang API Access , click New Credential.
  • Chọn Scope cho API .

 

  • Click Save.
  • Trên trang  API Access lúc này sẽ thấy API Credential vừa được tạo

 .

  • Click vào nó bạn sẽ thấy cặp key Client Secret và Client ID . Ngoài ra bạn cũng có thể Disable ,Enable hoặc Delete API Credential đó .

2 . Generate Tokens

 API.

Ở bước này bạn sẽ Generate ra cặp key "access_token" và "refresh_token" dựa vào cặp key  Client Secret và Client ID đã có ở bước trên .

Access Token có giới hạn là 5000  lần gọi trên 1 giờ , quá giới hạn API sẽ trả về error . Do đó bạn phải dùng Refresh Token để sinh ra Access Token mới .

Sample Request  :

curl 'https://api.us.onelogin.com/auth/oauth2/token' \
-X POST \
-H "Authorization: client_id:<client_id>, client_secret:<client_secret>" \
-H "Content-Type: application/json" \
-d '{ 
    "grant_type":"client_credentials"
}'

Sample Response :

{
    "status": {
        "error": false,
        "code": 200,
        "type": "success",
        "message": "Success"
    },
    "data": [
        {
            "access_token": "xx508xx63817x7sdsadsadsadsafsdgfds78f5xx34xxxxx51",
            "created_at": "2015-11-11T03:36:18.714Z",
            "expires_in": 36000,
            "refresh_token": "628x9x0xx447xx4x421x517dsfdsfdsfdsf5x4x1xx523xxxxx6x7x20",
            "token_type": "bearer",
            "account_id": 555555
        }
 ]
}

3 . Refresh Token API

Refresh Token có giá trị 45 ngày sau khi được sinh ra , nó được dùng để generate new Access Token .

Sample Request  :

curl 'https://api.<us_or_eu>.onelogin.com/auth/oauth2/token' \
-X POST \
-H "Authorization: client_id:<client_id>, client_secret:<client_secret>>" \
-H "Content-Type: application/json" \
-d '{
    "grant_type":"refresh_token",
    "access_token":"<access_token>",
    "refresh_token":"<refresh_token>"
}'

Sample Response :

{
    "status": {
        "error": false,
        "code": 200,
        "type": "success",
        "message": "Success"
    },
    "data": [
        {
            "access_token": "",
            "created_at": "2015-11-11T22:46:15.961Z",
            "expires_in": 36000,
            "refresh_token": "",
            "token_type": "bearer"
        }
    ]
}

3 . Create Session Login Token API 

Đây là API được dùng kết hợp với  Verify Factor API  (phía dưới) khi sử dụng tính năng MFA của OneLogin.

API này sẽ lấy được "device_type" và "device_id" và "state_token" cái mà mình đã thiết lập ở bước thêm chức năng xác thực 2 lần vào tài khoản OneLogin . 

  • device_type :  là Google Authencator mà mình đã thêm ở bước trên.
  • device_id : Là ID của điện thoại của mình dùng để nhận mã xác thực .

Nếu có nhiều yếu tố xác thực được thêm vào thì trong kết quả trả về của API sẽ có nhiều cặp giá trị phía trên .

Sample Request  :

curl 'https://api.<us_or_eu>.onelogin.com/api/1/login/auth' \
-X POST \
-H "Authorization: bearer: <access_token>" \
-H "Content-Type: application/json" \
-d '{
    "username_or_email": "<username_or_email>", 
    "password": "<password>", 
    "subdomain": "<subdomain>"
}'

Sample Response :

{
    "status": {
        "type": "success",
        "code": 200,
        "message": "MFA is required for this user",
        "error": false
    },
    "data": [
        {
            "user": {
                "email": "jennifer.hasenfus@onelogin.com",
                "username": "jhasenfus",
                "firstname": "Jennifer",
                "lastname": "Hasenfus",
                "id": 88888888
            },
            "state_token": "xf4330878444597bd3933d4247cc1xxxxxxxxxxx",
            "callback_url": "https://api.us.onelogin.com/api/1/login/verify_factor",
            "devices": [
                {
                    "device_type": "OneLogin OTP SMS",
                    "device_id": 111111
                },
                {
                    "device_type": "Google Authenticator",
                    "device_id": 444444
                }
            ]
        }
    ]
}

4 .Verify Factor API

Đây là API được dùng kết hợp với Create Session Login Token API  khi sử dụng tính năng MFA của OneLogin.

Bằng device_id và state_token được lấy ở bước trên , kết hợp với otp_token là mã số xác thưc được sinh ra hoặc được gửi lên điện thoại , bạn có thể xác thực được Request .

※Chú ý là có 2 trường hợp : xác nhận bằng tin nhắn SMS hoặc là bằng các mã xác thức được sinh ra tự động như là Google Authencator thì khác nhau .

  • Trường hợp sử dụng OneLogin OTP SMS :

         Bước 1 : 

                    Sample Request  : gửi request mà không có otp_token , lúc này Onelogin sẽ gửi mã xác thực otp_token tới điện thoại của mình.

curl 'https://api.<us_or_eu>.onelogin.com/api/1/login/verify_factor' \
-X POST \
-H "Authorization: bearer:<access_token>" \
-H "Content-Type: application/json" \
-d '{
"device_id": "&lt;device_id&gt;",
"state_token": "&lt;state_token&gt;"

}'

                    Sample Response :

{
    "status": {
        "type": "success",
        "code": 200,
        "message": "SMS token sent to your mobile device. Authentication pending.",
        "error": false
    }
}

 

          Bước 2 : 

                    Sample Request  : gửi Request với mã xác thực otp_token mà nhận được từ điện thoại .

curl 'https://api.<us_or_eu>.onelogin.com/api/1/login/verify_factor' \
-X POST \
-H "Authorization: bearer:<access_token>" \
-H "Content-Type: application/json" \
-d '{
    "otp_token": "<otp_token>",
    "device_id": "<device_id>",
    "state_token": "<state_token>"
}'

                      Sample Response :

{
    "status": {
        "type": "success",
        "code": 200,
        "message": "Success",
        "error": false
    },
    "data": [
        {
            "return_to_url": null,
            "user": {
                "username": "jhasenfus",
                "email": "jennifer.hasenfus@onelogin.com",
                "firstname": "Jennifer",
                "lastname": "Hasegawa",
                "id": 88888888
            },
            "status": "Authenticated",
            "session_token": "xxxxxxxxx8a4c07773a5454f946",
            "expires_at": "2016/01/26 02:21:47 +0000"
        }
    ]
}

 

  • Trường sử dụng Google Authenticator

Do otp_token được sinh ra tự động trên ứng dụng điện thoại 1 cách liên tục là được reset trong 1 thời gian ngắn khoảng mấy giây , nên trong trường hợp này ta bỏ qua bước 1 của OneLogin OTP SMS mà làm trực tiếp bước 2 của OneLogin OTP SMS.

Sample Request  : gửi Request với mã xác thực otp_token mà nhận được từ điện thoại .

curl 'https://api.<us_or_eu>.onelogin.com/api/1/login/verify_factor' \
-X POST \
-H "Authorization: bearer:<access_token>" \
-H "Content-Type: application/json" \
-d '{
    "otp_token": "<otp_token>",
    "device_id": "<device_id>",
    "state_token": "<state_token>"
}'

 Sample Response : otp_token được sinh ra tự động trên ứng dụng điện thoại 1 cách liên tục là được reset trong 1 thời gian ngắn khoảng mấy giây

{
    "status": {
        "type": "success",
        "code": 200,
        "message": "Success",
        "error": false
    },
    "data": [
        {
            "return_to_url": null,
            "user": {
                "username": "jhasenfus",
                "email": "jennifer.hasenfus@onelogin.com",
                "firstname": "Jennifer",
                "lastname": "Hasegawa",
                "id": 88888888
            },
            "status": "Authenticated",
            "session_token": "xxxxxxxxx8a4c07773a5454f946",
            "expires_at": "2016/01/26 02:21:47 +0000"
        }
    ]
}

  Ở bước này nếu thành công ta sẽ lấy được  session_token  giá trị này sẽ có hiệu lực trong 1 thời gian nhất định . Ta dùng nó đễ duy trì tính xác thực trong 1 thời gian nhất định .  

Để kiểm tra session_token có còn hiệu lực hay không ta dùng Create Session API 

 Sample Request:

curl 'https://{your_subdomain}.onelogin.com/session_via_api_token' \
-X POST \
-H "Content-Type: application/json" \
-d '{
    "session_token": "<your session token value>",
}'

Response Code :  200

  •  Java Code Sample 

package com.grandsphere.oneid.command.admin.auth;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.Security;
import java.text.ParseException;

import javax.net.ssl.HttpsURLConnection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.json.JSONObject;

import com.grandsphere.oneid.command.BusinessLogicException;
import com.grandsphere.oneid.entity.code.ReturnCodes;

public class OneloginOtpApiSender {

/** ロガー */
private static final Log log = LogFactory
		.getLog(OneloginOtpApiSender.class);

/** ONELOGIN SERVER URL */
private static final String ONELOGIN_GENERATE_TOKENS_URL = "https://api.us.onelogin.com/auth/oauth2/token";
private final static String USER_AGENT = "Mozilla/5.0";
private static final String CLIENT_SECRET = "81a45daxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
private static final String CLIENT_ID = "3a5e754545eeyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
private static final String AUTHORIZATION_HEADER = "client_id:" + CLIENT_ID
		+ "," + "client_secret:" + CLIENT_SECRET;

private static final String CREATE_SESSION_LOGIN_TOKEN_URL = "https://api.us.onelogin.com/api/1/login/auth";

private static final String USERNAME_OR_MAIL = "xxxxxxxx@xxxxxxx.net";
private static final String PASSWORD = "*************";
private static final String SUBDOMAIN = "gmo-internet";

private static final String VERIFY_FACTOR_URL = "https://api.us.onelogin.com/api/1/login/verify_factor";

private static String access_token_total = null;

// Generate ra cặp key "access_token" v&agrave; "refresh_token" dựa v&agrave;o cặp key  Client Secret v&agrave; Client ID
public static JSONObject generateTokens() throws BusinessLogicException,
		ParseException {
	try {
		// Could not generate DH keypairエラーを解決ため
		Security.addProvider(new BouncyCastleProvider());

		String urlParameters = "{\"grant_type\":\"client_credentials\"}";
		log.info("urlParameters : " + urlParameters);

		URL obj = new URL(ONELOGIN_GENERATE_TOKENS_URL);

		// Open connection
		HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

		// Specify POST method
		con.setRequestMethod("POST");

		// 4. Set the headers
		con.setRequestProperty("User-Agent", USER_AGENT);
		con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
		con.setRequestProperty("Content-Type", "application/json");
		con.setRequestProperty("Authorization", AUTHORIZATION_HEADER);
		con.setRequestProperty("Content-Length",
				Integer.toString(urlParameters.length()));
		con.setRequestProperty("charset", "utf-8");

		// Send post request
		con.setDoOutput(true);

		DataOutputStream wr = new DataOutputStream(con.getOutputStream());
		wr.writeBytes(urlParameters);
		wr.flush();
		wr.close();

		int responseCode = con.getResponseCode();

		log.info("\nSending 'POST' request to URL : "
				+ ONELOGIN_GENERATE_TOKENS_URL);
		log.info("Response Code : " + responseCode);

		BufferedReader in = new BufferedReader(new InputStreamReader(
				con.getInputStream(), "UTF-8"));
		String inputLine;
		StringBuffer response = new StringBuffer();

		while (null != in &amp;&amp; (inputLine = in.readLine()) != null) {
			response.append(inputLine);
		}

		in.close();
		con.disconnect();
		JSONObject object = null;
		object = new org.json.JSONObject(response.toString());

		log.info("Response Json : "
				+ object.getJSONObject("status").getString("message"));

		log.info("Response data : "
				+ object.getJSONArray("data").getJSONObject(0)
						.getString("access_token"));

		return object;
	} catch (MalformedURLException e2) {
		log.error(e2);
		throw new BusinessLogicException(
				ReturnCodes.ApiResponse.E_API_0001, e2.getMessage());
	} catch (IOException e1) {
		log.error(e1);
		throw new BusinessLogicException(
				ReturnCodes.ApiResponse.E_API_0001, e1.getMessage());
	}

}

//Refresh Token c&oacute; gi&aacute; trị 45 ng&agrave;y sau khi được sinh ra , n&oacute; được d&ugrave;ng để generate new Access Token .
public static JSONObject refreshTokens() throws BusinessLogicException,
		ParseException {
	try {
		// Could not generate DH keypairエラーを解決ため
		Security.addProvider(new BouncyCastleProvider());

		JSONObject genenate_token = OneloginOtpApiSender.generateTokens();
		String access_token = (String) genenate_token.getJSONArray("data")
				.getJSONObject(0).getString("access_token");
		String refresh_token = (String) genenate_token.getJSONArray("data")
				.getJSONObject(0).getString("refresh_token");

		String urlParameters = "{"
				+ "\"grant_type\":\"client_credentials\","
				+ "\"access_token\":\"" + access_token + "\","
				+ "\"refresh_token\":\"" + refresh_token + "\"" + "}";

		log.info("urlParameters : " + urlParameters);

		URL obj = new URL(ONELOGIN_GENERATE_TOKENS_URL);

		// Open connection
		HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

		// Specify POST method
		con.setRequestMethod("POST");

		// 4. Set the headers
		con.setRequestProperty("User-Agent", USER_AGENT);
		con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
		con.setRequestProperty("Content-Type", "application/json");
		con.setRequestProperty("Authorization", AUTHORIZATION_HEADER);
		con.setRequestProperty("Content-Length",
				Integer.toString(urlParameters.length()));
		con.setRequestProperty("charset", "utf-8");

		// Send post request
		con.setDoOutput(true);

		DataOutputStream wr = new DataOutputStream(con.getOutputStream());
		wr.writeBytes(urlParameters);
		wr.flush();
		wr.close();

		int responseCode = con.getResponseCode();

		log.info("\nSending 'POST' request to URL : "
				+ ONELOGIN_GENERATE_TOKENS_URL);
		log.info("Response Code : " + responseCode);

		BufferedReader in = new BufferedReader(new InputStreamReader(
				con.getInputStream(), "UTF-8"));
		String inputLine;
		StringBuffer response = new StringBuffer();

		while (null != in &amp;&amp; (inputLine = in.readLine()) != null) {
			response.append(inputLine);
		}

		in.close();
		con.disconnect();
		JSONObject object = null;
		object = new org.json.JSONObject(response.toString());

		log.info("Response Json : " + object);

		return object;
	} catch (MalformedURLException e2) {
		log.error(e2);
		throw new BusinessLogicException(
				ReturnCodes.ApiResponse.E_API_0001, e2.getMessage());
	} catch (IOException e1) {
		log.error(e1);
		throw new BusinessLogicException(
				ReturnCodes.ApiResponse.E_API_0001, e1.getMessage());
	}

}

//Create Session Login Token API  l&agrave; API được d&ugrave;ng kết hợp với  Verify Factor API  (ph&iacute;a dưới) khi sử dụng t&iacute;nh năng MFA của OneLogin.
public static JSONObject createSeesionLoginTokens()
		throws BusinessLogicException, ParseException {
	try {
		// Could not generate DH keypairエラーを解決ため
		Security.addProvider(new BouncyCastleProvider());
		JSONObject genenate_token = OneloginOtpApiSender.refreshTokens();
		access_token_total = (String) genenate_token.getJSONArray("data")
				.getJSONObject(0).getString("access_token");

		String urlParameters = "{" + "\"username_or_email\":\""
				+ USERNAME_OR_MAIL + "\"," + "\"password\":\"" + PASSWORD
				+ "\"," + "\"subdomain\":\"" + SUBDOMAIN + "\"" + "}";

		log.info("urlParameters : " + urlParameters);

		URL obj = new URL(CREATE_SESSION_LOGIN_TOKEN_URL);

		// Open connection
		HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

		// Specify POST method
		con.setRequestMethod("POST");

		// 4. Set the headers
		con.setRequestProperty("User-Agent", USER_AGENT);
		con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
		con.setRequestProperty("Content-Type", "application/json");
		con.setRequestProperty("Authorization", "bearer: "
				+ access_token_total);
		con.setRequestProperty("Content-Length",
				Integer.toString(urlParameters.length()));
		con.setRequestProperty("charset", "utf-8");

		// Send post request
		con.setDoOutput(true);

		DataOutputStream wr = new DataOutputStream(con.getOutputStream());
		wr.writeBytes(urlParameters);
		wr.flush();
		wr.close();

		int responseCode = con.getResponseCode();

		log.info("\nSending 'POST' request to URL : "
				+ CREATE_SESSION_LOGIN_TOKEN_URL);
		log.info("Response Code : " + responseCode);

		BufferedReader in = new BufferedReader(new InputStreamReader(
				con.getInputStream(), "UTF-8"));
		String inputLine;
		StringBuffer response = new StringBuffer();

		while (null != in &amp;&amp; (inputLine = in.readLine()) != null) {
			response.append(inputLine);
		}

		in.close();
		con.disconnect();
		JSONObject object = null;
		object = new org.json.JSONObject(response.toString());

		log.info("Response Json : " + object);

		return object;
	} catch (MalformedURLException e2) {
		log.error(e2);
		throw new BusinessLogicException(
				ReturnCodes.ApiResponse.E_API_0001, e2.getMessage());
	} catch (IOException e1) {
		log.error(e1);
		throw new BusinessLogicException(
				ReturnCodes.ApiResponse.E_API_0001, e1.getMessage());
	}

}

//Verify Factor API l&agrave; API được d&ugrave;ng kết hợp với Create Session Login Token API  khi sử dụng t&iacute;nh năng MFA của OneLogin.
public static JSONObject verifyFactor(String otp_token)
		throws BusinessLogicException, ParseException {
	try {
		// Could not generate DH keypairエラーを解決ため
		Security.addProvider(new BouncyCastleProvider());

		JSONObject session_login_token = OneloginOtpApiSender
				.createSeesionLoginTokens();
		String device_id = session_login_token.getJSONArray("data")
				.getJSONObject(0).getJSONArray("devices").getJSONObject(0)
				.getString("device_id");
		String state_token = session_login_token.getJSONArray("data")
				.getJSONObject(0).getString("state_token");

		String urlParameters = "{" + "\"otp_token\":\"" + otp_token + "\","
				+ "\"device_id\":\"" + device_id + "\","
				+ "\"state_token\":\"" + state_token + "\"" + "}";

		log.info("urlParameters : " + urlParameters);

		URL obj = new URL(VERIFY_FACTOR_URL);

		// Open connection
		HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

		// Specify POST method
		con.setRequestMethod("POST");

		// 4. Set the headers
		con.setRequestProperty("User-Agent", USER_AGENT);
		con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
		con.setRequestProperty("Content-Type", "application/json");
		con.setRequestProperty("Authorization", "bearer: "
				+ access_token_total);
		con.setRequestProperty("Content-Length",
				Integer.toString(urlParameters.length()));
		con.setRequestProperty("charset", "utf-8");

		// Send post request
		con.setDoOutput(true);

		DataOutputStream wr = new DataOutputStream(con.getOutputStream());
		wr.writeBytes(urlParameters);
		wr.flush();
		wr.close();

		int responseCode = con.getResponseCode();

		log.info("\nSending 'POST' request to URL : "
				+ CREATE_SESSION_LOGIN_TOKEN_URL);
		log.info("Response Code : " + responseCode);

		BufferedReader in = null;
		try {
			in = new BufferedReader(new InputStreamReader(
					con.getInputStream(), "UTF-8"));
		} catch (IOException e) {
			in = new BufferedReader(new InputStreamReader(
					con.getErrorStream(), "UTF-8"));
		}
		String inputLine;
		StringBuffer response = new StringBuffer();

		while (null != in &amp;&amp; (inputLine = in.readLine()) != null) {
			response.append(inputLine);
		}

		in.close();
		con.disconnect();
		JSONObject object = null;
		object = new org.json.JSONObject(response.toString());

		log.info("Response Json : " + object);

		return object;
	} catch (MalformedURLException e2) {
		log.error(e2);
		throw new BusinessLogicException(
				ReturnCodes.ApiResponse.E_API_0001, e2.getMessage());
	} catch (IOException e1) {
		log.error(e1);
		throw new BusinessLogicException(
				ReturnCodes.ApiResponse.E_API_0001, e1.getMessage());
	}

}

//Để kiểm tra session_token c&oacute; c&ograve;n hiệu lực hay kh&ocirc;ng ta d&ugrave;ng Create Session API 
public static int sessionViaApiToken(String session_token)
		throws BusinessLogicException, ParseException {
	try {
		// Could not generate DH keypairエラーを解決ため
		Security.addProvider(new BouncyCastleProvider());


		String urlParameters = "{" + "\"session_token\":\"" + session_token + "\"}";

		log.info("urlParameters : " + urlParameters);

		URL obj = new URL("https://gmo-internet.onelogin.com/session_via_api_token");

		// Open connection
		HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

		// Specify POST method
		con.setRequestMethod("POST");

		// 4. Set the headers
		con.setRequestProperty("User-Agent", USER_AGENT);
		con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
		con.setRequestProperty("Content-Type", "application/json");
		con.setRequestProperty("Content-Length",
				Integer.toString(urlParameters.length()));
		con.setRequestProperty("charset", "utf-8");

		// Send post request
		con.setDoOutput(true);

		DataOutputStream wr = new DataOutputStream(con.getOutputStream());
		wr.writeBytes(urlParameters);
		wr.flush();
		wr.close();

		int responseCode = con.getResponseCode();

		log.info("\nSending 'POST' request to URL : "
				+ CREATE_SESSION_LOGIN_TOKEN_URL);
		log.info("Response Code : " + responseCode);

		con.disconnect();

		return responseCode;
	} catch (MalformedURLException e2) {
		log.error(e2);
		throw new BusinessLogicException(
				ReturnCodes.ApiResponse.E_API_0001, e2.getMessage());
	} catch (IOException e1) {
		log.error(e1);
		throw new BusinessLogicException(
				ReturnCodes.ApiResponse.E_API_0001, e1.getMessage());
	}

}

}