Zend_OpenId_Provider puede usarse para implementar servidores
OpenID. Este capítulo ofrece ejemplos que muestran cómo
construir un servidor muy básico. Sin embargo, para la implementación de un servidor OpenID
de producción (como www.myopenid.com) puede
que tenga que lidiar con problemas más complejos.
El siguiente ejemplo incluye código para crear una cuenta de usuario
usando Zend_OpenId_Provider::register. El elemento link con
rel="openid.server" apunta a nuestro propio script de servidor. Si
envía esta identidad a un sitio habilitado para OpenID, se realizará
la autenticación en este servidor.
El código antes de la etiqueta <html> es solo un truco que crea automáticamente una cuenta de usuario. No necesitará ese código cuando use identidades reales.
Ejemplo 53.11. La identidad
<?php
// Set up test identity
define("TEST_SERVER", Zend_OpenId::absoluteURL("example-8.php"));
define("TEST_ID", Zend_OpenId::selfURL());
define("TEST_PASSWORD", "123");
$server = new Zend_OpenId_Provider();
if (!$server->hasUser(TEST_ID)) {
$server->register(TEST_ID, TEST_PASSWORD);
}
?>
<html><head>
<link rel="openid.server" href="<?php echo TEST_SERVER;?>" />
</head><body>
<?php echo TEST_ID;?>
</body></html>
El siguiente script de servidor de identidad maneja dos tipos de solicitudes
de sitios habilitados para OpenID (para asociación y autenticación). Ambos
son gestionados por el mismo método:
Zend_OpenId_Provider::handle. Los dos argumentos del
constructor de Zend_OpenId_Provider son URLs de
las páginas de inicio de sesión y confianza, que solicitan entrada del usuario final.
En caso de éxito, el método Zend_OpenId_Provider::handle
devuelve una cadena que debe pasarse de vuelta al sitio habilitado para OpenID. En
caso de fallo, devuelve FALSE. Este ejemplo devolverá una
respuesta HTTP 403 si
Zend_OpenId_Provider::handle falla. Obtendrá esta respuesta si
abre este script con un navegador web, porque envía una solicitud que no
cumple con OpenID.
Ejemplo 53.12. Proveedor de identidad simple
$server = new Zend_OpenId_Provider("example-8-login.php",
"example-8-trust.php");
$ret = $server->handle();
if (is_string($ret)) {
echo $ret;
} else if ($ret !== true) {
header('HTTP/1.0 403 Forbidden');
echo 'Forbidden';
}
![]() |
Nota |
|---|---|
Es una buena idea usar una conexión segura (HTTPS) para estos scripts, especialmente para los siguientes scripts interactivos, para evitar la divulgación de contraseñas. |
El siguiente script implementa una pantalla de inicio de sesión para un servidor
de identidad usando Zend_OpenId_Provider y redirige a esta página cuando
un usuario requerido aún no ha iniciado sesión. En esta página, un usuario introducirá su contraseña
para iniciar sesión.
Debe usar la contraseña "123" que se usó en el script de identidad anterior.
Al enviar, el script llama a Zend_OpenId_Provider::login
con la identidad y contraseña del usuario aceptado, y luego redirige de vuelta
al script principal del proveedor de identidad. En caso de éxito, el
método Zend_OpenId_Provider::login establece una sesión entre el
usuario y el proveedor de identidad y almacena la información sobre
el usuario, que ahora ha iniciado sesión. Todas las solicitudes siguientes del mismo usuario no
requerirán un procedimiento de inicio de sesión, incluso si provienen de otro sitio web
habilitado para OpenID.
![]() |
Nota |
|---|---|
Tenga en cuenta que esta sesión es solo entre el usuario final y el proveedor de identidad. Los sitios habilitados para OpenID no saben nada de ella. |
Ejemplo 53.13. Pantalla de inicio de sesión simple
<?php
$server = new Zend_OpenId_Provider();
if ($_SERVER['REQUEST_METHOD'] == 'POST' &&
isset($_POST['openid_action']) &&
$_POST['openid_action'] === 'login' &&
isset($_POST['openid_identifier']) &&
isset($_POST['openid_password'])) {
$server->login($_POST['openid_identifier'],
$_POST['openid_password']);
Zend_OpenId::redirect("example-8.php", $_GET);
}
?>
<html>
<body>
<form method="post">
<fieldset>
<legend>OpenID Login</legend>
<table border=0>
<tr>
<td>Name:</td>
<td>
<input type="text"
name="openid_identifier"
value="<?php echo htmlspecialchars($_GET['openid_identity']);?>">
</td>
</tr>
<tr>
<td>Password:</td>
<td>
<input type="text"
name="openid_password"
value="">
</td>
</tr>
<tr>
<td> </td>
<td>
<input type="submit"
name="openid_action"
value="login">
</td>
</tr>
</table>
</fieldset>
</form>
</body>
</html>
El hecho de que el usuario ya haya iniciado sesión no significa que la autenticación deba tener éxito necesariamente. El usuario puede decidir no confiar en sitios habilitados para OpenID particulares. La siguiente pantalla de confianza permite al usuario final tomar esa decisión. Esta elección puede hacerse únicamente para las solicitudes actuales o para siempre. En el segundo caso, la información sobre sitios de confianza/no confianza se almacena en una base de datos interna, y todas las siguientes solicitudes de autenticación de este sitio se manejarán automáticamente sin interacción del usuario.
Ejemplo 53.14. Pantalla de confianza simple
<?php
$server = new Zend_OpenId_Provider();
if ($_SERVER['REQUEST_METHOD'] == 'POST' &&
isset($_POST['openid_action']) &&
$_POST['openid_action'] === 'trust') {
if (isset($_POST['allow'])) {
if (isset($_POST['forever'])) {
$server->allowSite($server->getSiteRoot($_GET));
}
$server->respondToConsumer($_GET);
} else if (isset($_POST['deny'])) {
if (isset($_POST['forever'])) {
$server->denySite($server->getSiteRoot($_GET));
}
Zend_OpenId::redirect($_GET['openid_return_to'],
array('openid.mode'=>'cancel'));
}
}
?>
<html>
<body>
<p>A site identifying as
<a href="<?php echo htmlspecialchars($server->getSiteRoot($_GET));?>">
<?php echo htmlspecialchars($server->getSiteRoot($_GET));?>
</a>
has asked us for confirmation that
<a href="<?php echo htmlspecialchars($server->getLoggedInUser());?>">
<?php echo htmlspecialchars($server->getLoggedInUser());?>
</a>
is your identity URL.
</p>
<form method="post">
<input type="checkbox" name="forever">
<label for="forever">forever</label><br>
<input type="hidden" name="openid_action" value="trust">
<input type="submit" name="allow" value="Allow">
<input type="submit" name="deny" value="Deny">
</form>
</body>
</html>
Los servidores OpenID de producción normalmente admiten la Simple Registration Extension, que permite a los consumidores solicitar cierta información sobre el usuario al proveedor. En este caso, la página de confianza puede extenderse para permitir la introducción de los campos solicitados o la selección de un perfil de usuario específico.
Es posible combinar toda la funcionalidad del proveedor en un solo script. En
este caso, las URLs de inicio de sesión y confianza se omiten, y
Zend_OpenId_Provider asume que apuntan a la misma página
con el argumento GET adicional "openid.action".
![]() |
Nota |
|---|---|
El siguiente ejemplo no está completo. No proporciona código de interfaz gráfica para el usuario; en su lugar, realiza un inicio de sesión automático y una relación de confianza automática. Esto se hace solo para simplificar el ejemplo; un servidor de producción debería incluir algo de código de los ejemplos anteriores. |
Ejemplo 53.15. Todo junto
$server = new Zend_OpenId_Provider();
define("TEST_ID", Zend_OpenId::absoluteURL("example-9-id.php"));
define("TEST_PASSWORD", "123");
if ($_SERVER['REQUEST_METHOD'] == 'GET' &&
isset($_GET['openid_action']) &&
$_GET['openid_action'] === 'login') {
$server->login(TEST_ID, TEST_PASSWORD);
unset($_GET['openid_action']);
Zend_OpenId::redirect(Zend_OpenId::selfUrl(), $_GET);
} else if ($_SERVER['REQUEST_METHOD'] == 'GET' &&
isset($_GET['openid_action']) &&
$_GET['openid_action'] === 'trust') {
unset($_GET['openid_action']);
$server->respondToConsumer($_GET);
} else {
$ret = $server->handle();
if (is_string($ret)) {
echo $ret;
} else if ($ret !== true) {
header('HTTP/1.0 403 Forbidden');
echo 'Forbidden';
}
}
Si compara este ejemplo con los ejemplos anteriores divididos en
páginas separadas, verá solo una
diferencia además del código de despacho:
unset($_GET['openid_action']). Esta llamada a
unset() es necesaria para enrutar la siguiente solicitud al manejador principal.
De nuevo, el código antes de la etiqueta <html> es solo un truco para demostrar la funcionalidad. Crea una nueva cuenta de usuario y la asocia con un perfil (apodo y contraseña). Estos trucos no son necesarios en proveedores desplegados donde los usuarios finales se registran en servidores OpenID y completan sus perfiles. Implementar esta interfaz gráfica queda fuera del alcance de este manual.
Ejemplo 53.16. Identidad con perfil
<?php
define("TEST_SERVER", Zend_OpenId::absoluteURL("example-10.php"));
define("TEST_ID", Zend_OpenId::selfURL());
define("TEST_PASSWORD", "123");
$server = new Zend_OpenId_Provider();
if (!$server->hasUser(TEST_ID)) {
$server->register(TEST_ID, TEST_PASSWORD);
$server->login(TEST_ID, TEST_PASSWORD);
$sreg = new Zend_OpenId_Extension_Sreg(array(
'nickname' =>'test',
'email' => 'test@test.com'
));
$root = Zend_OpenId::absoluteURL(".");
Zend_OpenId::normalizeUrl($root);
$server->allowSite($root, $sreg);
$server->logout();
}
?>
<html>
<head>
<link rel="openid.server" href="<?php echo TEST_SERVER;?>" />
</head>
<body>
<?php echo TEST_ID;?>
</body>
</html>
Ahora debería pasar esta identidad al sitio web habilitado para OpenID (use el ejemplo de la Simple Registration Extension de la sección anterior), y este debería usar el siguiente script de servidor OpenID.
Este script es una variación del script del ejemplo "Todo junto". Usa
el mismo mecanismo de inicio de sesión automático, pero no contiene ningún código para una página
de confianza. El usuario ya confía para siempre en los scripts de ejemplo. Esta confianza fue
establecida llamando al método Zend_OpenId_Provider::allowSite()
en el script de identidad. El mismo método asocia el perfil con la
URL de confianza. Este perfil se devolverá automáticamente ante una solicitud de
la URL de confianza.
Para hacer que la Simple Registration Extension funcione, simplemente debe
pasar una instancia de Zend_OpenId_Extension_Sreg como segundo
argumento del método Zend_OpenId_Provider::handle().
Ejemplo 53.17. Proveedor con SREG
$server = new Zend_OpenId_Provider();
$sreg = new Zend_OpenId_Extension_Sreg();
define("TEST_ID", Zend_OpenId::absoluteURL("example-10-id.php"));
define("TEST_PASSWORD", "123");
if ($_SERVER['REQUEST_METHOD'] == 'GET' &&
isset($_GET['openid_action']) &&
$_GET['openid_action'] === 'login') {
$server->login(TEST_ID, TEST_PASSWORD);
unset($_GET['openid_action']);
Zend_OpenId::redirect(Zend_OpenId::selfUrl(), $_GET);
} else if ($_SERVER['REQUEST_METHOD'] == 'GET' &&
isset($_GET['openid_action']) &&
$_GET['openid_action'] === 'trust') {
echo "UNTRUSTED DATA" ;
} else {
$ret = $server->handle(null, $sreg);
if (is_string($ret)) {
echo $ret;
} else if ($ret !== true) {
header('HTTP/1.0 403 Forbidden');
echo 'Forbidden';
}
}
Construir proveedores OpenID es mucho menos común que construir
sitios habilitados para OpenID, por lo que este manual no cubre todas
las características de Zend_OpenId_Provider de forma exhaustiva, como se hizo con
Zend_OpenId_Consumer.
En resumen, Zend_OpenId_Provider contiene:
Un conjunto de métodos para construir una interfaz gráfica de usuario final que permite a los usuarios registrar y gestionar sus sitios de confianza y perfiles
Una capa de almacenamiento abstracta para almacenar información sobre usuarios, sus sitios y sus perfiles. También almacena asociaciones entre el proveedor y los sitios habilitados para OpenID. Esta capa es muy similar a la de la clase
Zend_OpenId_Consumer. También usa almacenamiento en archivos de forma predeterminada, pero puede usarse con otro backend.Una capa abstracta de asociación de usuarios que puede asociar el navegador web de un usuario con una identidad que ha iniciado sesión
La clase Zend_OpenId_Provider no intenta cubrir todas
las posibles características que pueden implementar los servidores OpenID, por ejemplo, certificados
digitales, pero puede extenderse fácilmente usando
Zend_OpenId_Extensions o mediante la extensión orientada a objetos estándar.
![[Note]](images/note.png)