I am using the Zend_OpenId_Consumer to provide OpenID access, the login is working fine, but when I call verify() I am recieving the error
`Wrong openid.return_to 'http://[host]/user/openid' != 'http://[host]/user/openid?[OpenIdResponse]
The issue as far as I can see is that the verify method is comparing the URL without the query part to the entire URL which includes all of the OpenID response information. It gets this url from Zend_OpenId::selfUrl()
I'm using the verify code from the doc pages
$consumer = new Zend_OpenId_Consumer();
if($this->_request->getParam('openid_mode')) {
$id = $this->_request->getParam('openid_claimed_id');
if($this->_request->getParam('openid_mode') == 'id_res') {
if($consumer->verify($this->_request->getParams(),$id)) {
$status = 'VALID ' . $id;
}
else {
$status = 'INVALID ' . $id;
}
}
elseif($this->_request->getParam('openid_mode') == 'cancel') {
$status = 'CANCELLED';
}
}
Am I doing something wrong here?
perhaps this is helpful
Integration with Zend_Controller
Finally a couple of words about
integration into Model-View-Controller
applications: such Zend Framework
applications are implemented using the
Zend_Controller class and they use
objects of the
Zend_Controller_Response_Http class to
prepare HTTP responses and send them
back to the user's web browser.
Zend_OpenId_Consumer doesn't provide
any GUI capabilities but it performs
HTTP redirections on success of
Zend_OpenId_Consumer::login and
Zend_OpenId_Consumer::check. These
redirections may work incorrectly or
not at all if some data was already
sent to the web browser. To properly
perform HTTP redirection in MVC code
the real Zend_Controller_Response_Http
should be sent to
Zend_OpenId_Consumer::login or
Zend_OpenId_Consumer::check as the
last argument.
zend.openid.consumer
strange, i've just tested OpenId_Consumer on my localserver with ZF 1.10.3...
no problem at all
my Action
public function openidAction() {
$this->view->status = "";
if ($this->getRequest()->isPost()) {
$consumer = new Zend_OpenId_Consumer();
if (!$consumer->login($this->getRequest()->getParam('openid_identifier'))) {
$this->view->status = "OpenID login failed.";
}
} else if ($this->getRequest()->getParam('openid_mode')) {
if ($this->getRequest()->getParam('openid_mode') == "id_res") {
$consumer = new Zend_OpenId_Consumer();
if ($consumer->verify($this->getRequest()->getParams(), $id)) {
$this->view->status = "VALID " . htmlspecialchars($id);
} else {
$this->view->status = "INVALID " . htmlspecialchars($id);
}
} else if ($_GET['openid_mode'] == "cancel") {
$this->view->status = "CANCELLED";
}
}
}
my View
<p><?php echo "{$this->status}" ?></p>
<form method="post">
<fieldset>
<legend>OpenID Login</legend>
<input type="text" name="openid_identifier" value=""/>
<input type="submit" name="openid_action" value="login"/>
</fieldset>
</form>
Related
Hello guys I'm new to composer thing. Previously I had configured dropbox manually in my codeigniter project but my head asked me to do it using composer now. I have configured composer somehow and installed dropbox using composer. Now this was my login function which I used before
public function login() {
// $this->CI->session->set_userdata('state', 1);
$this->CI->session->dropbox_success = false;
$oauth = new Dropbox_OAuth_PHP($this->CI->config->item('APP_KEY'), $this->CI->config->item('APP_SECRET'));
$this->dropbox = new Dropbox_API($oauth);
if ($this->CI->session->state) {
$state = $this->CI->session->state;
} else {
$this->CI->session->set_userdata('state', 1);
$state = 1;
}
switch ($state) {
/* In this phase we grab the initial request tokens
and redirect the user to the 'authorize' page hosted
on dropbox */
case 1 :
// echo "Step 1: Acquire request tokens\n";
$tokens = $oauth->getRequestToken();
// echo "<a href='".$oauth->getAuthorizeUrl(site_url())."' >Authorize</a>";
// header('Location: '. $oauth->getAuthorizeUrl());
echo "<img width='30px' src='" . base_url() . "somePAth'> Connect Dropbox";
$this->CI->session->set_userdata('state', 2);
$this->CI->session->set_userdata('oauth_tokens', $tokens);
return FALSE;
/* In this phase, the user just came back from authorizing
and we're going to fetch the real access tokens */
case 2 :
if (!$this->CI->session->oauth_tokens) {
$this->CI->session->set_userdata('state', 1);
header("Location: ?");
}
$oauth->setToken($this->CI->session->oauth_tokens);
$tokens = null;
try {
$tokens = $oauth->getAccessToken();
} catch (Exception $e) {
$this->CI->session->set_userdata('state', 1);
header("Location: ?");
return false;
}
$this->CI->session->set_userdata('state', 3);
$this->CI->session->set_userdata('oauth_tokens', $tokens);
header("Location: ?");
case 3 :
// echo "The user is authenticated\n";
$this->CI->session->dropbox_success = true;
$oauth->setToken($this->CI->session->oauth_tokens);
echo "<a class='btn btn-primary float-right' href=" . base_url('somePath') . ">Disconnect Dropbox</a>";
return true;
}
}
Now after I installed dropbox using composer and after going through the configration I created the app-info.json file and included the code which dropbox asked me to add in the code which is $oauth = dbx\AppInfo::loadFromJsonFile("../config/app-info.json"); in place of the second uncommented line but it's not working. It is throwing me this error.
ERROR : Exception of type 'Error' occurred with Message: Class 'dbx\AppInfo' not found in File D:\Ampps\www\softcake\application\libraries\Dropbox.php at Line 30
So can somebody please guide me what is it that I'm doing wrong and redirect me to some solution which would help me in configuring drop box in my app. Thanks in advance
I'm trying to implement a simple CSRF protection on a form, but I can't get it right. If someone can point out what I'm doing wrong, I would appreciate it.
The error: Every time I submit the form, I get "Invalid Submission2" because the token changes (after the form is submitted), since is being generated on the same page?
Edit -- I forgot to mention, another file (config.php) already has session_start().
<?php
class Module_Post extends Base_Module {
public function start()
{
requireLogin();
if (isset($_GET['act'])) {
switch($_GET['act']) {
case 'text':
$this->text();
break;
case 'image':
$this->image();
break;
default:
$this->text();
break;
}
} else {
$this->text();
}
}
private function text()
{
// Generate random unique token to prevent cross-site request forgery (CSRF).
if(empty($_SESSION['form_token']))
{
$form_token = md5(uniqid(rand(), TRUE));
$_SESSION['form_token'] = $form_token;
}
if(isset($_POST['submit']))
{
// Clean the content from cross-site scripting (xss)
$content = trim($_POST['content']);
$content = Xss::clean($content);
// Validate that the form token
if(!isset($_POST['form_token'], $_SESSION['form_token'])) {
$err = 'Invalid Submission';
} elseif ($_POST['form_token'] != $_SESSION['form_token']) {
$err = 'Invalid Submission2';
} elseif (strlen($content) < 10) {
$err = 'Your content contains too few characters.';
}
if(isset($err)) {
unset( $_SESSION['form_token']);
$this->setMessage($err, 'FAIL');
header('Location: index.php?mod=post');
exit;
}
// Insert database data here, then redirect
$this->setMessage('Your post was published successfully.', 'GOOD');
header('Location: index.php');
exit;
}
$this->tpl->assign('form_token', $form_token);
$this->tpl->display('new/text.tpl');
}
}
?>
The HTML (text.tpl file)
<form method='post' enctype='multipart/form-data' action='#'>
<fieldset>
<textarea rows="8" id="new_post" name="content" class="input-block-level"></textarea>
<input type="hidden" name="form_token" value="{$form_token}" />
<button type="submit" name="submit" class="btn btn-info pull-left">Create Post</button>
</fieldset>
</form>
You need to change this line
$this->tpl->assign('form_token', $form_token);
into:
$this->tpl->assign('form_token', $_SESSION['form_token']);
That's because you generate your token only with this condition:
if(empty($_SESSION['form_token']))
{
$form_token = md5(uniqid(rand(), TRUE));
$_SESSION['form_token'] = $form_token;
}
and unset it using this condition:
if(isset($err)) {
unset( $_SESSION['form_token']);
}
So if you send your form once and then reload page (without submitting form just url), $form_token variable is unknown because there is $_SESSION['form_token'] is not empty and then in your form you have empty token.
If you had displaying errors turned on in PHP you would see in this case in PHP:
Undefined variable: form_token in
At the moment I am attempting to create an application that passes on data to delete a row in my database. This row will be known by the ID passed on by the html file to js.
Currently I have a Html file, Javascript and PHP file which all work together to get this data passed in.
What im looking to do is secure it so no-one unauthorised can just send data to the javascript document in-order to delete the row.
HTML -- > JS --> PHP
JS:
function deleteListing(id) {
var answer = confirm("Are you sure you want to delete this listing?")
if (answer) {
$.post("assets/scripts/deleteListing.php", {
id: id
},
function (result) {
var response = jQuery.parseJSON(result);
if (response.available === true) {
location.reload();
} else if (response.available === false) {
// alert("FAILURE DELETING USER");
} else if (response.root === true) {
// alert("Cannot Delete Root User..");
}
});
} else {
return;
}
}
PHP:
<?
require("../../../assets/config/config.php");
$id_retrieve = $_POST['id'];
$data = new stdClass();
$sth= $dbh-> prepare("SELECT * FROM listings WHERE id='".$id_retrieve."'");
$sth -> execute();
$row = $sth -> fetch();
$data->available = true;
$dbh->exec("DELETE FROM listings WHERE id = '".$id_retrieve."'");
echo json_encode($data);
?>
Before anyone says the statement is not created using the prepared statement, I am aware of this and will fix it asap. Apart from that, is there anyway I can secure the Javascript file from unauthorised access? or could I limit it somehow?
Thanks!
There are a couple of solutions.
As #Tobias said above: Use sessions to handle the authentication. That will protect you some.
However, that alone doesn't stop Cross-Session attacks.
Take a look at this page: http://phpsec.org/projects/guide/2.html
It suggests putting a token value on the form and saving it in the session. That way, when the form is submitted you can compare the incoming token against the one in your session and verify that the form did, indeed, come from your site.
<?php
session_start();
if (isset($_POST['message']))
{
if (isset($_SESSION['token']) && $_POST['token'] == $_SESSION['token'])
{
$message = htmlentities($_POST['message']);
$fp = fopen('./messages.txt', 'a');
fwrite($fp, "$message<br />");
fclose($fp);
}
}
$token = md5(uniqid(rand(), true));
$_SESSION['token'] = $token;
?>
<form method="POST">
<input type="hidden" name="token" value="<?php echo $token; ?>" />
<input type="text" name="message"><br />
<input type="submit">
</form>
<?php
readfile('./messages.txt');
?>
I have coded some alerting system.
But let's not look at the system itself, Let's look at how will the system know that the system really did sent the alert/error to the browsing user.
I have made something so when you randomly go to ?alert=name, without doing any error, it will say 'No errors'.
But if the system makes you go to ?alert=name, it will echo the error.
How I handle posts
function postComment() {
if (!empty($_POST['name']) || !empty($_POST['comment'])) {
$comment = mysql_real_escape_string(htmlentities($_POST['comment']));
$guest = mysql_real_escape_string(htmlentities($_POST['name']));
}
$guestId = 1;
if (empty($guest)) {
$alert = 1;
return header('location: index.php?alert=name');
}
if (empty($comment)) {
$alert = 2;
return header('location: index.php?alert=comment');
}
if (!isset($_COOKIE['alreadyPosted'])) {
mysql_query("INSERT INTO `comments` (`comment_guest`, `guest_id`, `comment`, `comment_date`, `comment_time`) VALUES ('$guest', '$guestId', '$comment', CURDATE(), CURTIME())") or die(mysql_error());
header('Location: index.php?action=sucess');
setcookie(alreadyPosted, $cookieId+1, time() + 60);
} else {
$alert = 3;
header('location: index.php?alert=delay');
}
}
As you see, to check if user really getting that error, I will set $alert to whatever error number it is.
And to check if hes getting the error I will use this:
if (isset($_GET['alert']) == 'name') {
if ($alert == 1) {
echo 'hai';
} else {
echo 'No errors';
}
}
You will probably wonder why I am doing it this way.., well because I use 1 function for post, and my post function goes under the form, and i want the alerts to display up to the form.
Problem:
The variable either doesn't get set to the number that it is supposed to when running the function,
or.. something is blocking it from it.. I don't know..
My guess: Because the check for errors is located up to the postComment function before the variables even get set?
<?php
if (isset($_GET['alert']) == 'name') {
if ($alert == 1) {
echo 'hai';
} else {
echo 'No errors';
}
}
?>
<form action="index.php" method="POST">
<input type="text" name="name" placeholder="Your name here" class="field">
<textarea class="textarea" name="comment" placeholder="Your comment here..."></textarea>
<input type="submit" name="send" class="blue_button" value="Post Comment">
</form><input type="submit" name="" id="margin" class="blue_button" value="See all messages">
<br />
<?php
//Show the comments
showComments();
if (isset($_POST['send'])) {
postComment();
}
if (isset($_GET['delete']) == "comment"){
deleteComment();
}
echo '<br />';
?>
If it is, what is the solution?
Thanks!
Please don't start with the story about mysql_ function, I understood & I will use PDO instead, but I am using mysql_ at the moment for testing purposes
The problem is that you're redirecting on an error, and so the $alert variable does not get carried over.
To fix the problem add the alert type to the $_GET parameters:
function postComment()
{
// ...
if (empty($guest))
{
header('location: index.php?alert=name&alert_type=1');
exit;
}
// ...
}
And then when you check for the error:
if (isset($_GET['alert']) && 'name' == $_GET['alert'])
{
if (isset($_GET['alert_type']) && '1' == $_GET['alert_type'])
{
echo 'hai';
}
else
{
echo 'No errors';
}
}
Note also that I fixed the error here:
isset($_GET['alert']) == 'name'
That doesn't do what I think you think it does. What you want is:
isset($_GET['alert']) && 'name' == $_GET['alert']
(Excuse the order of the comparison; I prefer to have variables on the right for comparisons as it will cause a parse error if you miss a = -- much better than having it run but not do what you expect)
if you are a newbie, you better consider using client side scripting (viz javascript) for validation as using server side validation will simple make the process longer. but as you are facing problems, this might give you the solution.
as you are redirecting the page to index.php?alert=name', so $alert is never set initially when the page loads itself. when you call the function postcomment(), $alert is initiated but immediately destroyed when the system redirects. And as $alert never holds a value when you randomly visit the page, it shows no error.
I start saying that I HATE OpenID, because it's poorly implemented/documented.
I'm trying to use "openid-php-openid-2.2.2-24". Here the source code: https://github.com/openid/php-openid
When I try to use the authentication example, it returns to me:
"You have successfully verified https://www.google.com/accounts/o8/id?id=[...] as your identity.
No PAPE response was sent by the provider."
but there's no shadow of email, nickname or fullname of google openid login data.
While reading the file ("/openid/examples/consumer/finish_auth.php"), I note that SREG variables have to be printed between the "You have successfully verified" and "No PAPE response" messages, but they don't:
$success = sprintf('You have successfully verified ' .
'%s as your identity.',
$esc_identity, $esc_identity);
if ($response->endpoint->canonicalID) {
$escaped_canonicalID = escape($response->endpoint->canonicalID);
$success .= ' (XRI CanonicalID: '.$escaped_canonicalID.') ';
}
$sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
$sreg = $sreg_resp->contents();
if (#$sreg['email']) {
$success .= " You also returned '".escape($sreg['email']).
"' as your email.";
}
if (#$sreg['nickname']) {
$success .= " Your nickname is '".escape($sreg['nickname']).
"'.";
$_SESSION['nickname'] = escape($sreg['nickname']);
}
if (#$sreg['fullname']) {
$success .= " Your fullname is '".escape($sreg['fullname']).
"'.";
}
$pape_resp = Auth_OpenID_PAPE_Response::fromSuccessResponse($response);
if ($pape_resp) {
[...]
} else {
$success .= "<p>No PAPE response was sent by the provider.</p>";
}
I've tried to print the content of $sreg['email'], $sreg['nickname'] and $sreg['fullname'], but they return all blank contents (null/empty values).
I need to retrieve the email address of the account which users use to login in..
Dante
To get the question off the unanswered list, I post dante's answer here as answer:
I solved my problem.
Example usage of AX in PHP OpenID: Example usage of AX in PHP OpenID
After 2 days of research, I've just now found the answer ("but Google uses AX (attribute exchange) instead of SReg for additional data"). Why Google must always be so different?
However, the code in that stackoverflow answer page doesn't work for me (my hosting server returns 500 internal server error code).
So, I post here "my code" (it's so rough):
oid_ax_common.php
<?php
// Circumnavigate bugs in the GMP math library that can be result in signature
// validation errors
define('Auth_OpenID_BUGGY_GMP', true);
$path_extra = dirname(dirname(dirname(__FILE__)));
$path = ini_get('include_path');
$path = $path_extra . PATH_SEPARATOR . $path;
ini_set('include_path', $path);
function displayError($message) {
$error = $message;
include './index.php';
exit(0);
}
function doIncludes() {
/**
* Require the OpenID consumer code.
*/
require_once "Auth/OpenID/Consumer.php";
/**
* Require the "file store" module, which we'll need to store
* OpenID information.
*/
require_once "Auth/OpenID/FileStore.php";
/**
* Require the Simple Registration extension API.
*/
//require_once "Auth/OpenID/SReg.php";
require_once "Auth/OpenID/AX.php";
/**
* Require the PAPE extension module.
*/
require_once "Auth/OpenID/PAPE.php";
}
doIncludes();
global $pape_policy_uris;
$pape_policy_uris = array(
PAPE_AUTH_MULTI_FACTOR_PHYSICAL,
PAPE_AUTH_MULTI_FACTOR,
PAPE_AUTH_PHISHING_RESISTANT
);
function &getStore() {
/**
* This is where the example will store its OpenID information.
* You should change this path if you want the example store to be
* created elsewhere. After you're done playing with the example
* script, you'll have to remove this directory manually.
*/
$store_path = null;
if (function_exists('sys_get_temp_dir')) {
$store_path = sys_get_temp_dir();
}
else {
if (strpos(PHP_OS, 'WIN') === 0) {
$store_path = $_ENV['TMP'];
if (!isset($store_path)) {
$dir = 'C:\Windows\Temp';
}
}
else {
$store_path = #$_ENV['TMPDIR'];
if (!isset($store_path)) {
$store_path = '/tmp';
}
}
}
$store_path = './tmp/';
$store_path .= DIRECTORY_SEPARATOR . '_php_consumer_test';
if (!file_exists($store_path) &&
!mkdir($store_path)) {
print "Could not create the FileStore directory '$store_path'. ".
" Please check the effective permissions.";
exit(0);
}
$r = new Auth_OpenID_FileStore($store_path);
return $r;
}
function &getConsumer() {
/**
* Create a consumer object using the store object created
* earlier.
*/
$store = getStore();
$r = new Auth_OpenID_Consumer($store);
return $r;
}
function getScheme() {
$scheme = 'http';
if (isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') {
$scheme .= 's';
}
return $scheme;
}
function getReturnTo() {
return sprintf("%s://%s:%s%s/oid_ax_receive.php",
getScheme(), $_SERVER['SERVER_NAME'],
$_SERVER['SERVER_PORT'],
dirname($_SERVER['PHP_SELF']));
}
function getTrustRoot() {
return sprintf("%s://%s:%s%s/",
getScheme(), $_SERVER['SERVER_NAME'],
$_SERVER['SERVER_PORT'],
dirname($_SERVER['PHP_SELF']));
}
?>
oid_ax_send.php
<?php
require_once "oid_ax_common.php";
// Starts session (needed for YADIS)
session_start();
function getOpenIDURL() {
// Render a default page if we got a submission without an openid
// value.
if (empty($_GET['openid_identifier'])) {
$error = "Expected an OpenID URL.";
include './index.php';
exit(0);
}
return $_GET['openid_identifier'];
}
function run() {
// https://www.google.com/accounts/o8/id
// $openid = 'http://openid-provider.appspot.com/';
$openid = 'https://www.google.com/accounts/o8/id';
// $openid .= getOpenIDURL();
$consumer = getConsumer();
// Begin the OpenID authentication process.
$auth_request = $consumer->begin($openid);
// Create attribute request object
// See http://code.google.com/apis/accounts/docs/OpenID.html#Parameters for parameters
// Usage: make($type_uri, $count=1, $required=false, $alias=null)
$attribute[] = Auth_OpenID_AX_AttrInfo::make('http://axschema.org/contact/email',2,1, 'email');
$attribute[] = Auth_OpenID_AX_AttrInfo::make('http://axschema.org/namePerson/first',1,1, 'firstname');
$attribute[] = Auth_OpenID_AX_AttrInfo::make('http://axschema.org/namePerson/last',1,1, 'lastname');
// Create AX fetch request
$ax = new Auth_OpenID_AX_FetchRequest;
// Add attributes to AX fetch request
foreach($attribute as $attr){
$ax->add($attr);
}
// Add AX fetch request to authentication request
$auth_request->addExtension($ax);
// No auth request means we can't begin OpenID.
if (!$auth_request) {
displayError("Authentication error; not a valid OpenID.");
}
/* $sreg_request = Auth_OpenID_SRegRequest::build(
// Required
array('nickname'),
// Optional
array('fullname', 'email'));
if ($sreg_request) {
$auth_request->addExtension($sreg_request);
} */
$policy_uris = null;
if (isset($_GET['policies'])) {
$policy_uris = $_GET['policies'];
}
$pape_request = new Auth_OpenID_PAPE_Request($policy_uris);
if ($pape_request) {
$auth_request->addExtension($pape_request);
}
// Redirect the user to the OpenID server for authentication.
// Store the token for this authentication so we can verify the
// response.
// For OpenID 1, send a redirect. For OpenID 2, use a Javascript
// form to send a POST request to the server.
if ($auth_request->shouldSendRedirect()) {
$redirect_url = $auth_request->redirectURL(getTrustRoot(),
getReturnTo());
// If the redirect URL can't be built, display an error
// message.
if (Auth_OpenID::isFailure($redirect_url)) {
displayError("Could not redirect to server: " . $redirect_url->message);
} else {
// Send redirect.
header("Location: ".$redirect_url);
}
} else {
// Generate form markup and render it.
$form_id = 'openid_message';
$form_html = $auth_request->htmlMarkup(getTrustRoot(), getReturnTo(),
false, array('id' => $form_id));
// Display an error if the form markup couldn't be generated;
// otherwise, render the HTML.
if (Auth_OpenID::isFailure($form_html)) {
displayError("Could not redirect to server: " . $form_html->message);
} else {
print $form_html;
}
}
}
run();
?>
oid_ax_receive.php
<?php
require_once "oid_ax_common.php";
// Starts session (needed for YADIS)
session_start();
function escape($thing) {
return htmlentities($thing);
}
function run() {
$consumer = getConsumer();
// Complete the authentication process using the server's
// response.
$return_to = getReturnTo();
$response = $consumer->complete($return_to);
// Check the response status.
if ($response->status == Auth_OpenID_CANCEL) {
// This means the authentication was cancelled.
$msg = 'Verification cancelled.';
} else if ($response->status == Auth_OpenID_FAILURE) {
// Authentication failed; display the error message.
$msg = "OpenID authentication failed: " . $response->message;
} else if ($response->status == Auth_OpenID_SUCCESS) {
// Get registration informations
$ax = new Auth_OpenID_AX_FetchResponse();
$obj = $ax->fromSuccessResponse($response);
// Print me raw
echo '<pre>';
print_r($obj->data);
echo '</pre>';
exit;
$pape_resp = Auth_OpenID_PAPE_Response::fromSuccessResponse($response);
if ($pape_resp) {
if ($pape_resp->auth_policies) {
$success .= "<p>The following PAPE policies affected the authentication:</p><ul>";
foreach ($pape_resp->auth_policies as $uri) {
$escaped_uri = escape($uri);
$success .= "<li><tt>$escaped_uri</tt></li>";
}
$success .= "</ul>";
} else {
$success .= "<p>No PAPE policies affected the authentication.</p>";
}
if ($pape_resp->auth_age) {
$age = escape($pape_resp->auth_age);
$success .= "<p>The authentication age returned by the " .
"server is: <tt>".$age."</tt></p>";
}
if ($pape_resp->nist_auth_level) {
$auth_level = escape($pape_resp->nist_auth_level);
$success .= "<p>The NIST auth level returned by the " .
"server is: <tt>".$auth_level."</tt></p>";
}
} else {
$success .= "<p>No PAPE response was sent by the provider.</p>";
}
}
include './index.php';
}
run();
?>
Enjoy.
Dante
P.S.: to complete the opera of OpenID, although I solved my problem with user info / login data with Google, I still have one problem with Light OpenID (https://stackoverflow.com/questions/10735708/lightopenid-openid-authurl-does-not-return-any-value).
If you want to help me, we will completely work out and conclude with the OpenID story.