1. 程式人生 > >CAS統一登入認證(12): 通過oauth2.0單點登入Afterlogic webmail

CAS統一登入認證(12): 通過oauth2.0單點登入Afterlogic webmail

  這段時間在研究CAS單點登入,已做了十幾個軟體的整合登入,有demo,有實際的各種應用軟體,目前最難啃的就是這個webmail整合登入,一是因為郵箱系統本身安全性高,二是要通過擴充套件外掛和 API介面,三是網上沒有找到有價值的資料,該修改那個檔案,全靠看原始碼除錯摸索。

1.整合效果

點選單點登入,如果已登入CAS,會直接跳入郵箱介面,沒有登入CAS,會先跳轉到CAS登入,登入後再自動跳轉到郵箱介面。

2. cas整合Oauth2.0技術,參見昨天寫的文章:https://blog.csdn.net/oLinBSoft/article/details/82493745

3. Afterlogic webmail 要開通ouath2.0登入,主要設定如下

4. 測試oauth模組。使用的是php 第三方的oauth模組

在目錄 htdocs\webmail\libraries\OAuthClient 有很多如facebook,twitter,github等等的連線程式碼,我複製的是login_with_twitter.php檔案到caslogin.php 檔案,再做修改,修改後原文如下:

<?php

	require('http.php');
	require('oauth_client.php');

	$client = new oauth_client_class;
	$client->debug = 1;
	$client->debug_http = 1;
	$client->server = 'Linbsoft';  //你的服務名稱
	$client->redirect_uri = 'http://'.$_SERVER['HTTP_HOST'].
		dirname(strtok($_SERVER['REQUEST_URI'],'?')).'/caslogin.php';
	$client->client_id = '88889999';   //你在cas oauth service設定的應用Id
	$application_line = __LINE__;
	$client->client_secret = '12345678acedfrfrf';  //你在cas oauth service設定的應用client_secret
	$client->grant_type = 'authorization_code';

	if(strlen($client->client_id) == 0
	|| strlen($client->client_secret) == 0)
		die('沒有client_id或client_secret');
	if(($success = $client->Initialize()))
	{
		if(($success = $client->Process()))
		{
			if(strlen($client->access_token))
			{
				$success = $client->CallAPI(
					'https://author.linbsoft.com/cas/oauth2.0/profile', 
					'GET', array(), array('FailOnAccessError'=>true), $user);
			}
			else
				$success = strlen($client->error = $client->access_token_error) === 0;
		}
		$success = $client->Finalize($success);
	}
	if($client->exit)
		exit;
	if($success)
	{
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>CAS OAuth 2 client results</title>
</head>
<body>
<?php
		echo '<h1>Retrieved the CAS profile of ', HtmlSpecialChars($user->id), 
			' successfully!</h1>';
		echo '<pre>', HtmlSpecialChars(print_r($user, 1)), '</pre>';
?>
</body>
</html>
<?php
	}
	else
	{
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>OAuth client error</title>
</head>
<body>
<h1>OAuth client error</h1>
<pre>Error: <?php echo HtmlSpecialChars($client->error); ?></pre>
</body>
</html>
<?php
	}

?>

5.如果順利,可以測試與cas伺服器 oauth2.0連線成功取回使用者資訊

6.但真正起作用的並不是這個檔案,這只是測試說明可以配置了,現在開始配置webmail的單點登入

7.修改htdocs\webmail\libraries\OAuthClient\oauth_client.php檔案,在相應位置增加如下幾行

			case 'Linbsoft':
				$this->oauth_version = '2.0';
				$this->dialog_url = 'https://author.linbsoft.comn/cas/oauth2.0/authorize?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}';
				$this->access_token_url = 'https://author.linbsoft.com/cas/oauth2.0/accessToken';
				break;

8. 在 htdocs\webmail\data\plugins\external-services\connectors目錄,原來有facebook,google,twitter等目錄,把twitter目錄複製到同目錄下linbsoft目錄,修改linbsoft目錄下的index.php,完整程式碼如下:

<?php

class CExternalServicesConnectorLinbsoft extends CExternalServicesConnector
{
	public static $ConnectorName = 'linbsoft';
	public static function GetSupportedScopes()
	{
		return array('auth');
	}
	public static function CreateClient($oTenant)
	{
		$oClient = null;
		$oSocial = $oTenant->getSocialByName(self::$ConnectorName);
		
		if(isset($oSocial) && $oSocial->SocialAllow)
		if(isset($oSocial))
		{
			$sRedirectUrl = rtrim(\MailSo\Base\Http::SingletonInstance()->GetFullUrl(), '\\/ ').'/?external-services=' . self::$ConnectorName;
			if (!strpos($sRedirectUrl, '://localhost'))
			{
				$sRedirectUrl = str_replace('http:', 'http:', $sRedirectUrl);
			}
			require(PSEVEN_APP_ROOT_PATH.'libraries/OAuthClient/http.php');
			require(PSEVEN_APP_ROOT_PATH.'libraries/OAuthClient/oauth_client.php');

			$oClient = new \oauth_client_class;
			$oClient->debug = self::$Debug;
			$oClient->debug_http = self::$Debug;
			$oClient->server = 'Linbsoft';
			$oClient->redirect_uri = $sRedirectUrl;
			$oClient->client_id = $oSocial->SocialId;
			$oClient->client_secret = $oSocial->SocialSecret;
			$oClient->grant_type = 'authorization_code';
		}
		return $oClient;
	}	
	public static function Init($oTenant = null)
	{
		parent::Init($oTenant);

		$bResult = false;
		$oUser = null;

		$oClient = self::CreateClient($oTenant);
		
		if($oClient)
		{
			if(($success = $oClient->Initialize()))
			{
				if(($success = $oClient->Process()))
				{
					if(strlen($oClient->access_token))
					{

						$success = $oClient->CallAPI(
							'https://author.linbsoft.com/cas/oauth2.0/profile',
							'GET',
							array(),
							array('FailOnAccessError'=>true),
							$oUser
						);
					}
				}
				$success = $oClient->Finalize($success);
			}
			if($oClient->exit)
			{
				$bResult = false;
				exit;
			}
			if($success && $oUser)
			{
				$aSocial = array(
					'type' => self::$ConnectorName,
					'id' => $oUser->id,
					'name' => $oUser->cn,
					'email' => isset($oUser->attributes->mail) ? $oUser->attributes->mail : '',
					'access_token' => $oClient->access_token,
					'scopes' => self::$Scopes
				);
				\CApi::Log('social_user_' . self::$ConnectorName);
				\CApi::LogObject($oUser);
				$bResult = $aSocial;
			}
			else
			{
				$bResult = false;
				$oClient->ResetAccessToken();
				self::_socialError($oClient->error, self::$ConnectorName);
			}
		}
		return $bResult;
	}
}

9. 修改htdocs\webmail\data\settings\config.php檔案

增加如紅框所示

10. 修改htdocs\data\settings\settings.php檔案

11.重啟apache24和hmailserver服務,即可看見登入頁多了一個單點登入的圖示。

使用單點登入後,除非關閉瀏覽器,否則,退出郵箱系統,輸入地址可以無需登入再次進入郵箱,因此,退出郵箱後,要記得關閉瀏覽器。