Heim  >  Artikel  >  Backend-Entwicklung  >  Beispiel einer PHP-Single-Sign-On-Implementierungslösung

Beispiel einer PHP-Single-Sign-On-Implementierungslösung

黄舟
黄舟Original
2017-02-28 09:18:591316Durchsuche

Zusammenfassung:

In diesem Artikel werden hauptsächlich die Analyse und das Design eines universellen Single-Sign-On-Systems unter Verwendung von Webservice-, Sitzungs- und Cookie-Technologien vorgestellt. Die spezifische Implementierungssprache ist PHP. Single Sign-On, im Englischen auch Single Sign On oder kurz SSO genannt, ist ein wichtiger Bestandteil der umfassenden Benutzerverarbeitung in aktuellen Unternehmen und Netzwerkunternehmen. Die Definition von SSO besteht darin, dass sich Benutzer in mehreren Anwendungssystemen nur einmal anmelden müssen, um auf alle gegenseitig vertrauenswürdigen Anwendungssysteme zuzugreifen.

Motivation:

Freunde, die die vollständige Anmeldemethode von ucenter verwendet haben, sollten wissen, dass dies eine typische Beobachtermusterlösung ist. Das User Center ist ein Subjekt, und die Registrierung und Löschung seiner Beobachter erfolgt einheitlich im Backend von ucenter. Jede Unteranwendungsstelle entspricht einem Beobachter. Jede Anmeldeaktion im Benutzercenter löst ein JS-Skript aus, um die W3C-Standard-Subsite-Anmeldeschnittstelle (api/uc.php) zurückzurufen.

Ich denke, die Nachteile dieser Methode liegen hauptsächlich in zwei Punkten: 1. Wenn zu viele Unterseiten vorhanden sind, erhöht sich die Rückrufschnittstelle entsprechend. Dies liegt an der Begrenzung der Anzahl verteilter Unterseiten . So steuern Sie es, damit die Anmeldeeffizienz nicht zu niedrig und schwer zu erfassen ist. 2. Wenn ein Problem mit der Rückrufschnittstelle einer bestimmten Unterstation auftritt, bleibt der Standard-Anmeldevorgang hängen (die Ausführungszeit des Anmeldeprogramms). kann eingeschränkt werden, aber wenn ein entsprechendes Problem vorliegt, wird die Rückrufschnittstelle der Unterstation hinter der Unterstation aufgerufen Nicht mehr

Aufgrund der oben genannten Probleme habe ich während des eigentlichen Entwicklungsprozesses ein weiteres einzelnes Schild entworfen -on-System

1. Beschreibung des Anmeldeprinzips

Technischer Implementierungsmechanismus des Single Sign-On: Wenn der Benutzer zum ersten Mal auf das Anwendungssystem 1 zugreift, weil er Wenn er sich noch nicht angemeldet hat, wird er zum Anmelden an das Authentifizierungssystem weitergeleitet. Basierend auf den vom Benutzer bereitgestellten Anmeldeinformationen führt das Authentifizierungssystem eine Identitätsüberprüfung durch. Wenn es die Validierung besteht, sollte ein Authentifizierungsnachweis zurückgegeben werden Wenn der Benutzer auf andere Anwendungen zugreift, wird er dieses Ticket als seinen eigenen Authentifizierungsnachweis mitbringen. Nachdem das Anwendungssystem die Anfrage erhalten hat, wird es zur Überprüfung an das Authentifizierungssystem weitergeleitet Wenn die Überprüfung bestanden wird, kann der Benutzer auf Anwendungssystem 2 und Anwendungssystem 3 zugreifen, ohne sich erneut anzumelden.

Es ist ersichtlich, dass zur Implementierung von SSO die folgenden Hauptfunktionen erforderlich sind:

a ) Alle Anwendungssysteme verfügen über ein gemeinsames Identitätsauthentifizierungssystem.

b) Alle Anwendungssysteme können Ticketinformationen identifizieren und extrahieren.

c) Die Anwendung kann automatisch angemeldete Benutzer identifizieren Stellen Sie fest, ob sich der aktuelle Benutzer angemeldet hat, und vervollständigen Sie damit die Single-Sign-On-Funktion.

Basierend auf den oben genannten Grundprinzipien habe ich eine Reihe von Single-Sign-On-Systemprogrammen in PHP-Sprache entworfen, die jetzt implementiert wurden offizieller Produktionsserverbetrieb. Dieses Systemprogramm verwendet die Ticketinformationen mit der eindeutigen Sitzungs-ID des gesamten Systems als Medium, um die gesamten Site-Informationen des aktuellen Online-Benutzers (Anmeldestatusinformationen und andere benutzerweite Site-Informationen, die verarbeitet werden müssen) abzurufen.

2. Prozessbeschreibung:

Anmeldevorgang:

1. Melden Sie sich zum ersten Mal auf einer Website an:

a) Der Benutzer gibt den Benutzernamen + das Passwort ein und sendet eine Anmeldeanfrage an das Benutzerverifizierungszentrum

b) Wenn er sich gerade auf der Website anmeldet, überprüft das Benutzerverifizierungszentrum über die Webservice-Anfrage die Legitimität des Benutzernamens und Passwort. Wenn die Überprüfung bestanden wird, wird ein Ticket generiert, um den Benutzer der aktuellen Sitzung zu identifizieren, und die Site-ID der aktuell angemeldeten Unterseite wird im Benutzercenter aufgezeichnet. Abschließend wird

c) zurückgegeben erhaltene Benutzerdaten und Eintrittskarte zur Unterseite. Wenn die Überprüfung fehlschlägt, wird der entsprechende Fehlerstatuscode zurückgegeben.

d) Gemäß dem von der Webservice-Anfrage im vorherigen Schritt zurückgegebenen Ergebnis meldet die aktuelle Unterseite den Benutzer an: Wenn der Statuscode Erfolg anzeigt, speichert die aktuelle Seite das Ticket über das Cookie davon Die Site zeichnet den Anmeldestatus des Benutzers auf. Wenn der Statuscode einen Fehler anzeigt, erhält der Benutzer eine entsprechende Meldung zum Anmeldefehler.

2. Wenn der Benutzer angemeldet ist, geht er zu einem anderen Unterabschnitt:

a) Überprüfen Sie den Anmeldestatus des Benutzers über das Cookie oder die Sitzung der Website: Wenn die Überprüfung bestanden wurde, geben Sie den Normalen ein Andernfalls überprüft das Benutzercenter den Anmeldestatus des Benutzers (sendet ein Ticket an das Benutzerüberprüfungscenter. Wenn die Überprüfung erfolgreich ist, wird die lokale Anmeldeverarbeitung für die zurückgegebenen Benutzerinformationen durchgeführt.) nicht eingeloggt.

Abmeldevorgang

a) Die aktuelle Abmeldung löscht den Anmeldestatus des Benutzers für die Site und die eindeutige Zufalls-ID des lokal gespeicherten Benutzers für die gesamte Site

b) Löschen Sie über die Webservice-Schnittstelle die eindeutige Zufalls-ID, die auf der gesamten Site aufgezeichnet wurde. Die Webservice-Schnittstelle kehrt zurück, meldet den Javascript-Code anderer angemeldeter Unterseiten ab und diese Site gibt diesen Code aus.

c) js-Code greift auf das W3C-Standard-Abmeldeskript der entsprechenden Site zu

3. Codebeschreibung:

Der relevante Code, der in diesem Artikel enthalten ist Wenn Sie interessiert sind, können Sie zum Herunterladen auf den Download-Link am Ende dieses Artikels klicken.

1. Anmeldevorgang:

Ab dem Öffnen des Browsers muss die erste Unterseite, die sich anmeldet, die Methode UClientSSO::loginSSO() aufrufen. Diese Methode gibt eine zufällige ID zurück, die für die gesamte Site eindeutig ist und zur Identifizierung des Benutzers verwendet wird. Diese zufällige ID wurde durch das Cookie dieser Website in UClientSSO::loginSSO() gespeichert, d. h. die Unterseite behält den Stub der Login-ID des Benutzers auf dieser Website.

a) Die UClientSSO::loginSSO()-Methode lautet wie folgt:

<?php
/**
 * 用户验证中心 登陆用户处理
 *
 * @param string $username   - 用户名
 * @param string $password   - 用户原始密码
 * @param boolean $remember   - 是否永久记住登陆账号
 * @param boolean $alreadyEnc  - 传入的密码是否已经经过simpleEncPass加密过
 *
 * @return array  - integer $return[&#39;status&#39;] 大于 0:返回用户 ID,表示用户登录成功
 *                        -1:用户不存在,或者被删除
 *                        -2:密码错
 *                                                 -11:验证码错误
 *                     string $return[&#39;username&#39;]   : 用户名
 *                     string $return[&#39;password&#39;]   : 密码
 *                     string $return[&#39;email&#39;]    : Email
 */

static public function loginSSO($username, $password, $remember=false, $alreadyEnc=false) {
self::_init();
self::_removeLocalSid();
$ret = array();

//
//1. 处理传入webservice接口的参数
//
$_params = array(
        &#39;username&#39; => $username,
        &#39;password&#39; => $alreadyEnc ? trim($password) : self::simpleEncPass(trim($password)),
        &#39;ip&#39;    => self::onlineip(),
        &#39;siteFlag&#39; => self::$site,
        &#39;remember&#39; => $remember
);
$_params[&#39;checksum&#39;] = self::_getCheckSum($_params[&#39;username&#39;] . $_params[&#39;password&#39;] .
$_params[&#39;ip&#39;] . $_params[&#39;siteFlag&#39;] . $_params[&#39;remember&#39;]);

//
// 2.调用webservice接口,进行登陆处理
//
$aRet = self::_callSoap(&#39;loginUCenter&#39;, $_params);

if (intval($aRet[&#39;resultFlag&#39;]) > 0 && $aRet[&#39;sessID&#39;]) {
//成功登陆
//设置本地session id
self::_setLocalSid($aRet[&#39;sessID&#39;]);

//设置用户中心的统一session id脚本路径
self::$_synloginScript = urldecode($aRet[&#39;script&#39;]);

$ret = $aRet[&#39;userinfo&#39;];
} else {

$ret[&#39;status&#39;] = $aRet[&#39;resultFlag&#39;];
}

return $ret;
}//end of function         

//b) 用户验证中心的webservice服务程序,接收到登陆验证请求后,调用UCenter::loginUCenter()方法来处理登陆请求。
/**
* 用户验证中心 登陆用户处理
*
* @param string $username
* @param string $password
* @param string $ip
* @param string $checksum
* @return array
*/
static public function loginUCenter($username, $password, $ip, $siteFlag, $remember=false) {
self::_init();
session_start();
$ret = array();
$arr_login_res   = login_user($username, $password, $ip);
$res_login     = $arr_login_res[&#39;status&#39;];        //
$ret[&#39;resultFlag&#39;] = $res_login;

if ($res_login < 1) {
//登陆失败
} else {

//登陆成功
$_SESSION[self::$_ucSessKey] = $arr_login_res;

$_SESSION[self::$_ucSessKey][&#39;salt&#39;] =
self::_getUserPassSalt($_SESSION[self::$_ucSessKey][&#39;username&#39;], $_SESSION[self::$_ucSessKey][&#39;password&#39;]);

$ret[&#39;userinfo&#39;] = $_SESSION[self::$_ucSessKey];
$ret[&#39;sessID&#39;]  = session_id();    //生成全站的唯一session id,作为ticket全站通行

//
//合作中心站回调登陆接口(设置用户中心的统一session id)
//
self::_createCoSitesInfo();
$uinfo = array();
$_timestamp = time();
$_rawCode = array(
            &#39;action&#39; => &#39;setSid&#39;,
            &#39;sid&#39;  => $ret[&#39;sessID&#39;],
            &#39;time&#39;  => $_timestamp,
);
if ($remember) {
$uinfo = array(
                &#39;remember&#39; => 1,
                &#39;username&#39; => $username,
                &#39;password&#39; => $password
);
}

$ret[&#39;script&#39;] = &#39;&#39;;
$_rawStr = http_build_query(array_merge($_rawCode, $uinfo));

//
// 合作站点的全域cookie设置脚本地址
//
foreach ((array)self::$_coSitesInfo as $_siteInfo) {
$_code = self::authcode($_rawStr, &#39;ENCODE&#39;, $_siteInfo[&#39;key&#39;]);
$_src = $_siteInfo[&#39;url&#39;] . &#39;?code=&#39; . $_code . &#39;&time=&#39; . $_timestamp;
$ret[&#39;script&#39;] .= urlencode(&#39;&#39;);
}

//
// 记住已登陆战
//
self::registerLoggedSite($siteFlag, $ret[&#39;sessID&#39;]);

unset($ret[&#39;userinfo&#39;][&#39;salt&#39;]);
}

return $ret;
}

?>



2. Nach erfolgreicher Anmeldung auf der Website wird die lokale Benutzeranmeldungsverarbeitung durchgeführt und die anschließende Überprüfung, ob der Benutzer angemeldet ist, nur lokal durchgeführt. (Für den lokalen Zugriff auf die Statusinformationen des angemeldeten Benutzers stellen Sie ihn bitte so ein, dass er nach dem Schließen des Browsers beendet wird.)

3. Wenn Sie den Anmeldestatus des Benutzers ermitteln, rufen Sie bitte zuerst den lokalen Überprüfungsprozess auf , erneut aufrufen Die Methode UClientSSO::checkUserLogin() geht zum Benutzercenter, um den Anmeldestatus des Benutzers zu ermitteln.

a) Die UClientSSO::checkUserLogin()-Methode lautet wie folgt:

<?php
 /**
 * 用户单点登陆验证函数
 *
 * @return array  - integer $return[&#39;status&#39;] 大于 0:返回用户 ID,表示用户登录成功
 *                                                  0:用户没有在全站登陆
 *                        -1:用户不存在,或者被删除
 *                        -2:密码错
 *                        -3:未进行过单点登陆处理
 *                                                 -11:验证码错误
 *                     string $return[&#39;username&#39;]   : 用户名
 *                     string $return[&#39;password&#39;]   : 密码
 *                     string $return[&#39;email&#39;]    : Email
 */
 public static function checkUserLogin(){
 self::_init();
 $ret = array();
 $_sessId = self::_getLocalSid();
 if (empty($_sessId)) {
 //永久记住账号处理
 if(isset($_COOKIE[_UC_USER_COOKIE_NAME]) && !empty($_COOKIE[_UC_USER_COOKIE_NAME])) {
 
 //
 // 根据cookie里的用户名和密码判断用户是否已经登陆。
 //
 $_userinfo = explode(&#39;|g|&#39;, self::authcode($_COOKIE[_UC_USER_COOKIE_NAME], &#39;DECODE&#39;, self::$_authcodeKey));
 
 $username = $_userinfo[0];
 $password = isset($_userinfo[1]) ? $_userinfo[1] : &#39;&#39;;
 if (empty($password)) {
 $ret[&#39;status&#39;] = -3;
 } else {
 return self::loginSSO($username, $password, true, true);
 }
 
 } else {
 $ret[&#39;status&#39;] = -3;
 }
 
 } else {
 //
 //本站原先已经登陆过,通过保留的sesson id存根去用户中心验证
 //
 $_params = array(
             &#39;sessId&#39;  => $_sessId,
             &#39;siteFlag&#39; => self::$site,
             &#39;checksum&#39; => md5($_sessId . self::$site . self::$_mcComunicationKey)
 );
 $aRet = self::_callSoap(&#39;getOnlineUser&#39;, $_params);
 if (intval($aRet[&#39;resultFlag&#39;]) > 0) {
 //成功登陆
 $ret = $aRet[&#39;userinfo&#39;];
 } else {
 $ret[&#39;status&#39;] = $aRet[&#39;resultFlag&#39;];
 }
 }
 
 return $ret;
 }       
 
 b) 用户验证中心的webservice服务程序,接收到检验登陆的请求后,调用UCenter::getOnlineUser()方法来处理登陆请求:
 [php]/**
 * 根据sid,获取当前登陆的用户信息
 *
 * @param string $sessId    - 全站唯一session id,用做ticket
 * @return array
 */
 /**
 * 根据sid,获取当前登陆的用户信息
 *
 * @param string $sessId    - 全站唯一session id,用做ticket
 * @return array
 */
 static public function getOnlineUser($sessId, $siteFlag) {
 self::_init();
 session_id(trim($sessId));
 session_start();
 
 $ret = array();
 $_userinfo = $_SESSION[self::$_ucSessKey];
 
 if (isset($_userinfo[&#39;username&#39;]) && isset($_userinfo[&#39;password&#39;]) &&
 self::_getUserPassSalt($_userinfo[&#39;username&#39;], $_userinfo[&#39;password&#39;])) {
 $ret[&#39;resultFlag&#39;] = "1";
 $ret[&#39;userinfo&#39;] = $_userinfo;
 
 self::registerLoggedSite($siteFlag, $sessId);        //记住已登陆战
 unset($ret[&#39;userinfo&#39;][&#39;salt&#39;]);
 } else {
 $ret[&#39;resultFlag&#39;] = "0";
 }
 
 return ($ret);
 }
 ?>



4. Rufen Sie während der einmaligen Abmeldung auf UClientSSO::logoutSSO()-Methode. Wenn der Aufruf erfolgreich ist und Sie möchten, dass sich andere angemeldete Websites sofort abmelden, rufen Sie bitte die Methode UClientSSO::getSynloginScript() auf, um das W3C-Standardskript abzurufen und auf der Seite auszugeben.

a) Die UClientSSO::logoutSSO()-Methode lautet wie folgt:

<?php
/**
* 全站单点登出
* - 通过webservice请求注销掉用户的全站唯一标识
*
* @return integer  1: 成功
*                   -11:验证码错误
*/
public static function logoutSSO(){
    self::_init();
    $_sessId = self::_getLocalSid();
    //
    //本站没有登陆的话,不让同步登出其他站
    //
    if (empty($_sessId)) {
        self::_initSess(true);
        return false;
    }
    $_params = array(
        &#39;sessId&#39;  => $_sessId,
        &#39;siteFlag&#39; => self::$site,
        &#39;checksum&#39; => md5($_sessId . self::$site . self::$_mcComunicationKey)
    );
    $aRet = self::_callSoap(&#39;logoutUCenter&#39;, $_params);
    if (intval($aRet[&#39;resultFlag&#39;]) > 0) {
        //成功登出
        self::_removeLocalSid();        //移除本站记录的sid存根
        self::$_synlogoutScript = urldecode($aRet[&#39;script&#39;]);
        $ret = 1;
    } else {
        $ret = $aRet[&#39;resultFlag&#39;];
    }
    return intval($ret);
}          [/php]
    b) 用户验证中心的webservice服务程序,接收到全站登出请求后,调用UCenter::loginUCenter()方法来处理登陆请求:
/**
* 登出全站处理
*
* @param string - 全站唯一session id,用做ticket
* @return boolean
*/
static public function logoutUCenter($sessId) {
    self::_init();
    session_id(trim($sessId));
    session_start();
    $_SESSION = array();
    return empty($_SESSION) ? true : false;
}
?>



IV 🎜>
1. Benutzerauthentifizierungscenter-Einstellungen

a) Die vom Benutzerauthentifizierungscenter für die Unterseite bereitgestellte Webservice-Service-Schnittstellendatei, nämlich UserSvc.php, wird in hostname/webapps bereitgestellt /port/ UserSvc.php. Um den WSDL-Inhalt anzuzeigen, besuchen Sie bitte http://www.php.cn/ UserSvc.php?wsdl

b) Die User Center-Benutzer-Single-Point-Service-Klassendatei ist UCenterSSO.class.php und die Datei Der Pfad befindet sich in Hostname/webapps/include/UCenterSSO.class.php. Diese Datei ist die Serverklasse für die Single-Sign-In-Verarbeitung des Benutzers und wird von hostname/webapps/port/UserSvc.php aufgerufen. Wird verwendet, um die Anmeldeinformationen des Benutzers, Statusinformationen darüber, ob eine Einzelpunktanmeldung, eine Einzelabmeldung usw. erfolgen soll, abzurufen.

c) Das Benutzerverifizierungszentrum erfüllt die W3C-Standards und verwendet Cookies zur Aufzeichnung. Die Skriptdatei zum Löschen der eindeutigen Zufalls-ID des Benutzers auf der gesamten Website lautet hostname/webapps/port/cookie_mgr.php.

2 Die Subsite-Einstellungen
A) Bitte, bitte, uclientsso.class.php wird im Service-Client-Verzeichnis des User Centers bereitgestellt. Nach der Bereitstellung ändern Sie bitte die letzte Zeile von UClientSSO::setSite('1'); Der Parameterwert ist die Identifikations-ID, die jeder Site einheitlich vom Benutzerverifizierungscenter zugewiesen wird.

b) Bedienen Sie den Client im Bereitgestelltes Benutzercenter Übertragen Sie im API-Verzeichnis unter dem Paket bitte das Skript logout_sso.php hierher und schreiben Sie ein Verarbeitungsskript zum Abmelden von dieser Site.

c) Im Codeabschnitt zur Überprüfung des Benutzeranmeldestatus auf der Unterseite wird eine zusätzliche Single-Sign-On-Überprüfungsverarbeitung im Benutzercenter hinzugefügt.

Das heißt, überprüfen Sie zunächst den Anmeldestatus des Benutzers über diese Website. Wenn die Überprüfung fehlschlägt, gehen Sie zur Überprüfung zum Benutzercenter. Für den Überprüfungsvorgang ist der Aufruf der Schnittstelle UClientSSO::checkUserLogin(); erforderlich. Die Bedeutung der Schnittstelle finden Sie in den Codekommentaren.

d) Verwenden Sie im Abmeldeverarbeitungsskript der Zweigstelle UClientSSO::getSynlogoutScript();, um die Skriptzeichenfolgenausgabe zu erhalten.


5. Erweiterte Funktionen:
1. Alle Online-Benutzer aufzeichnen und verfolgen

Da alle Benutzeranmeldungen über das Benutzerverifizierungscenter erfolgen müssen Benutzer Die Tickets werden im Verifizierungszentrum generiert, und in der Speichertabelle kann eine Zuordnungstabelle zwischen dem Benutzer und dem Ticket (Sitzungs-ID) erstellt werden. Erhalten Sie eine Datensatzliste aller Online-Benutzer.

Wenn es in Zukunft erforderlich ist, den Benutzerstatus zu verfolgen, um andere Funktionen zu implementieren, verfolgen Sie einfach diese Zuordnungstabelle. Weitere Funktionen können sein: Abrufen einer Liste der Online-Benutzer, Ermitteln des Online-Status des Benutzers, Ermitteln der Anzahl der Online-Benutzer usw.

2. Spezielle statistische Verarbeitung

Da die gesamte Systemanmeldung und -abmeldung über das Benutzerverifizierungszentrum erfolgen muss, können spezielle Benutzerstatistiken verarbeitet werden. Zum Beispiel die Anzahl der Benutzeranmeldungen pro Tag, die Anmeldezeit, die Ablaufzeit des Anmeldestatus, der Trend der Anzahl der Online-Benutzer in jedem Zeitraum usw.


6. Andere Angelegenheiten:                                                                                  Der Status geht verloren, wenn der Browser geschlossen wird. Jede Zweigstelle muss Sitzungen oder Cookies wie folgt verarbeiten:
a) Websites, die den Benutzeranmeldestatus im Sitzungsmodus aufzeichnen

Bitte fügen Sie den folgenden Code am Anfang des öffentlichen Skripts der Website hinzu






b) Websites, die Cookies verwenden, um den Benutzeranmeldestatus aufzuzeichnen

Bitte setzen Sie die Cookie-Gültigkeitsdauer auf Null.

<?php
 session_write_close();
 ini_set(&#39;session.auto_start&#39;, 0);          //关闭session自动启动
 ini_set(&#39;session.cookie_lifetime&#39;, 0);      //设置session在浏览器关闭时失效
 ini_set(&#39;session.gc_maxlifetime&#39;, 3600); //session在浏览器未关闭时的持续存活时间   
 ?>
Das Obige ist der Inhalt des Beispiels der PHP-Version der Single-Sign-In-Implementierungslösung. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!





-->

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn