php-openid library not returning SREG attributes? - php

I'm testing and learning the php-openid library at here: https://github.com/openid/php-openid
I downloaded the whole package and uploaded examples/consumer to http://www.example.com/openid and also uploaded Auth to http://www.example.com/Auth because my website only needs to be a relying party.
It's working correctly when I tested it with one of my openids and it displays "You have successfully verified xxxxx as your identity. "
However, it DOES NOT return any SREG attributes such as email or name which my openid profile does have these information.
I didn't make any change to any of the consumer example files (index.php, try_auth.php, finish_auth.php, nor common.php), so the code looks like this:
In try_auth.php:
$sreg_request = Auth_OpenID_SRegRequest::build(
// Required
array('nickname'),
// Optional
array('fullname', 'email'));
if ($sreg_request) {
$auth_request->addExtension($sreg_request);
}
In finish_auth.php:
$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']).
"'.";
}
if (#$sreg['fullname']) {
$success .= " Your fullname is '".escape($sreg['fullname']).
"'.";
}
I tried:
$sreg = $sreg_resp->contents();
print_r($sreg);
But it turned out to be an empty array:
Array
(
)
I tried:
https://www.google.com/accounts/o8/id
yahoo.com
ichsie.myopenid.com
And it all ends up with an empty array of $sreg.
I tried lightopenid which uses AX rather than SREG:
contact/email
namePerson
And they are correctly returning the values.
So how can I make the php-openid library return the attributes I need?

Does the provider actually returned the SREG attributes? What is the HTTP response you are sending from try_auth.php? What is the HTTP request that you received on finish_auth.php?

Related

Magento Integration With T-Hub

am setting up a sand box for a T-Hub Integration with Magento and quickbooks. I've set my life site up locally using WAMP server, and now Its on to trying to tie that local Magento site into T-hub.
The first error that I received stated the
"Connection to Magento store failed. Service authentication failure - Notice: Undefined index: httponly in c:\wamp\www\testsite\appcode\core\mage\Core\Model\Session\Abtract\Varien.php on line 98."
After some searching I found the the general consensus on that one was I had to put an ssl on my local server, done, that problem's gone. Now I'm get a general error message that simply says "Connection to Magento Failed"
I used the test page that atandra included with their files which returned this:
<RESPONSE Version="4.1">
<Envelope>
<Command>GETORDERS</Command>
<StatusCode>9001</StatusCode>
<StatusMessage>
Service authentication failure - Warning: array_key_exists() expects parameter 2 to be array, string given in C:\wamp\www\adamsarms\app\code\core\Mage\Captcha\Model\Observer.php on line 166
</StatusMessage>
<Provider>Magento</Provider>
</Envelope>
</RESPONSE>
Which kicks back to this is the php file:
public function checkUserLoginBackend($observer)
{
$formId = 'backend_login';
$captchaModel = Mage::helper('captcha')->getCaptcha($formId);
$loginParams = Mage::app()->getRequest()->getPost('login', array());
$login = array_key_exists('username', $loginParams) ? $loginParams['username'] : null;
if ($captchaModel->isRequired($login)) {
if (!$captchaModel->isCorrect($this->_getCaptchaString(Mage::app()->getRequest(), $formId))) {
$captchaModel->logAttempt($login);
Mage::throwException(Mage::helper('captcha')->__('Incorrect CAPTCHA.'));
}
}
$captchaModel->logAttempt($login);
return $this;
}
This line is the one it directly points to:
$login = array_key_exists('username', $loginParams) ? $loginParams['username'] : null;
I'm not sure which direction I need to go to fix this error to make t-hub start talking to magento proper, I've included everything that I've got, if someone needs more information please let me know, I just need a better understanding of what might be causing this error to possibly find a path to fixing it.
This is an issue with a Legacy codebase with the T-Hub extension. It was created for PHP 5.3 & Magento versions 1.4 & below. They really should update this thing since people are using it.
The companies official response is this: http://support4.atandra.com/index.php?/Knowledgebase/Article/View/92/4/magento-array_key_exists-error
Which is horrible because it relies on overriding core files.
What's going on is Mage_Captcha_Model_Observer has an event checkUserLoginBackend() that gets fired. This expects the POST info for 'login' to be a certain format. This is something that has changed over the years since legacy code does not have it in this format.
This is a really hacky fix. But it's better than overriding core magento files.
Change the CheckUser() function of Mage/Thub/Model/Run/Run.php to this (I've removed some of their comments):
public function CheckUser()
{
try {
$username = $this->RequestParams['USERID'];
$password = $this->RequestParams['PASSWORD'];
//here we just set the POST to our specified format..
//which is what the observer model thinks it should be
Mage::app()->getRequest()->setPost('login', array(
'username' => $username,
'password' => $password
));
$user = Mage::getSingleton('admin/user');
$userRole = Mage::getSingleton('admin/role');
if ($user->authenticate($username, $password)) {
$loadRole = $userRole->load($user->getRoles($user));
} else {
print($this->xmlErrorResponse($this->RequestParams['COMMAND'], '9000',
'Order download service authentication failure - Login/Password supplied did not match', $this->STORE_NAME, ''));
exit;
}
} catch (Exception $e) {
$this->Msg[] = "Critical Error CheckUser (Exception e)=" . $e->getMessage(); //BB 11Nov2014
print($this->xmlErrorResponse($this->RequestParams['COMMAND'], '9001',
'Service authentication failure - ' . " " . $e->getMessage(), $this->STORE_NAME, ''));
// End - <TIBB> 13Dec2011
exit;
}
}
Another alternative is to extend the Mage_Captcha_Model_Observer class with your own version that removes those array checks in checkUserLoginBackend().

API Request $_POST returning empty array

I'm using Zurmo and trying to create a new account using REST API. I followed this documentation precisely: http://zurmo.org/wiki/rest-api-specification-accounts to pass the required parameters as json array.
This is my php code:
public function actionCreateOrUpdate()
{
$params=$_POST;
$modelClassName=$this->getModelName();
foreach ($params as $param)
{
if (!isset($param))
{
$message = Zurmo::t('ZurmoModule', 'Please provide data.');
throw new ApiException($message);
}
$r=$this->GetParam($param);
$res= array('status' => 'SUCCESS', 'data' => array($r));
print_r(json_encode($res,true));
}
}
function GetParam ($param){
$modelClassName=$this->getModelName();
if (isset($param['mobile_id'] ) && !$param['mobile_id']=='' &&!$param['mobile_id']==null)
{ $id=$param['mobile_id'];
$params=array();
foreach ($param as $k => $v) {
if(!($k=='mobile_id')) {
$params[$k] = $v;}
}
if ($params=null){$message = Zurmo::t('ZurmoModule', 'Please provide data.');
throw new ApiException($message);}
$tableName = $modelClassName::getTableName();
$beans = ZurmoRedBean::find($tableName, "mobile_id = '$id'");
if (count($beans) > 0)
{
$result = $this->processUpdate($id, $params);
}else{
$result = $this->processCreate($params,$id);
}
}
return $result;
}
The problem is that the $_POST method is returning an empty array. While debugging I tried to use print_r($_POST) and it also returned an empty array. I also tried to pass parameters as plain text and got the same result. I tried $_GET method and it worked. I think the problem is in the $_POST method, maybe I need to change something in my .php files. Any ideas please?
You should first hit the api with static data, to check if it works fine, then try to integrate php within that static data. You will need to read the documentation for which action accepts which format, and which method is supported(GET OR POST). Then try die(); , before sending if the array formed is as per the documentation.
I had similar issue when creating Account using REST API from java client. The problem was I did not send the proper POST request.
Another symptom also was on server side print_r(file_get_contents("php://input"),true); php code returned the correct request data.
Specifically the root cause was:
The Content-Type HTTP header was not "application/x-www-form-urlencoded"
The value field value in POST request was not properly encoded ( I used java.net.URLEncoder.encode method to overcome this)
After fixing these it worked.

PHP-PKPass Not working with iOS 7 add the date and time that the pass was signed using the S/MIME signing-time attribute in PHP

Hi im new to ios 7 and php
ive been trying to make this PHP-PKPass Class to work with ios 7 it works fine with my Safari browser I can visualize the ticket when i try to download the package to add it to my passbook safari tells me "Cannot download the file"
this is the link where it have the sample running with my certificates
i looked into the phone logs it says:
The passTypeIdentifier or teamIdentifier provided may not match your certificate, or the certificate trust chain could not be verified.
all my certificates work fine the json is correct since i can visualize it on my Mac, the research that ive done so far points to the package needing to be signed with with the server date time not enforced in ios 6 but enforced in ios 7
anybody can help out with adding the date and time that the pass was signed using the S/MIME signing-time attribute via php to the current php class?
protected function createSignature($manifest) {
$paths = $this->paths();
file_put_contents($paths['manifest'], $manifest);
$pkcs12 = file_get_contents($this->certPath);
$certs = array();
if(openssl_pkcs12_read($pkcs12, $certs, $this->certPass) == true) {
$certdata = openssl_x509_read($certs['cert']);
$privkey = openssl_pkey_get_private($certs['pkey'], $this->certPass );
if(!empty($this->WWDRcertPath)){
if(!file_exists($this->WWDRcertPath)){
$this->sError = 'WWDR Intermediate Certificate does not exist';
return false;
}
openssl_pkcs7_sign($paths['manifest'], $paths['signature'], $certdata, $privkey, array(), PKCS7_BINARY | PKCS7_DETACHED, $this->WWDRcertPath);
}else{
openssl_pkcs7_sign($paths['manifest'], $paths['signature'], $certdata, $privkey, array(), PKCS7_BINARY | PKCS7_DETACHED);
}
$signature = file_get_contents($paths['signature']);
$signature = $this->convertPEMtoDER($signature);
file_put_contents($paths['signature'], $signature);
return true;
} else {
$this->sError = 'Could not read the certificate';
return false;
}
}
Try passing your certificates and keys in as file references. E.g.
openssl_pkcs7_sign($paths['manifest'],
$paths['signature'],
'file://' . $certs['cert'],
array('file://' . $certs['cert'], $this->certPass),
array(),
PKCS7_BINARY|PKCS7_DETACHED,
$this->WWDRcertPath);
I created a new pass ID, generated a new p12 certificate it works now!!!
Thanks for your help :)

OpenID Implementation for Google.. 400 Bad Request

So I'm trying to get a grasp of OpenID, and I feel I understand the theory, etc... now it's come to implementing it. I've got a very basic setup that sends a curl request to the google provider address..
https://www.google.com/accounts/o8/id
parses the returned XRDS xml file
<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)">
<XRD>
<Service priority="0">
<Type>http://specs.openid.net/auth/2.0/server</Type>
<Type>http://openid.net/srv/ax/1.0</Type>
<Type>http://specs.openid.net/extensions/ui/1.0/mode/popup</Type>
<Type>http://specs.openid.net/extensions/ui/1.0/icon</Type>
<Type>http://specs.openid.net/extensions/pape/1.0</Type>
<URI>https://www.google.com/accounts/o8/ud</URI>
</Service>
</XRD>
</xrds:XRDS>
After retrieving the actual provider for google from their XRDS document I redirect using this function...
public function RedirectToEndpoint() {
$params = array();
$params['openid.mode'] = 'checkid_setup';
$params['openid.ns'] = 'http://specs.openid.net/auth/2.0';
$params['openid.claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select';
$params['openid.identity'] = 'http://specs.openid.net/auth/2.0/identifier_select';
$params['openid.return_to'] = $this->URLs['return_to'];
$params['openid.realm'] = $this->URLs['realm'];
$join = stripos($this->URLs['openid_server'], '?') ? '&' : '?';
$redirect_to = $this->URLs['openid_server'] . $join . $this->array2url($params);
if (headers_sent()){ // Use JavaScript to redirect if content has been previously sent (not recommended, but safe)
echo '<script language="JavaScript" type="text/javascript">window.location=\'';
echo $redirect_to;
echo '\';</script>';
}else{ // Default Header Redirect
header('Location: ' . $redirect_to);
}
}
The array2url is a simple function which converts the assoc array $params to append to the query string.
The generated url is such...
https://www.google.com/accounts/o8/ud?openid.mode=checkid_setup&openid.ns=http://specs.openid.net/auth/2.0&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select&openid.identity=http://specs.openid.net/auth/2.0/identifier_select&openid.return_to=http://learn.local/openid/return.php&openid.realm=http://learn.local/openid/index.html&
However, you end up at a page requested is invalid. And a nice 400 Bad Request.. any ideas?
All in all, I couldn't feel more stupid! It came down to setting my realm correctly. I had a realm which lead to my return address being out of the available "scope" so to speak. For future people who run into a 400 error, it might be..
$openid->SetReturnAddress(('http://learn.local/openid/return.php')); //.return_to
$openid->SetDomain(('http://learn.local/openid/index.html')); //Realm
A poorly configured realm.. facepalm
It is now...
$openid->SetDomain(('http://learn.local')); //Realm

Example usage of AX in PHP OpenID

I'm using JanRain's PHP OpenID library. It comes with example script which is using SReg extension. But I want it to work with Google (and it works for auth actually), but Google uses AX (attribute exchange) instead of SReg for additional data. For some reason, JanRain's library is missing AX support in example script, and code comments in AX script are out of my understanding, though comments in SReg script are clear as 1-2-3.
Does anyone know how to implement AX without too much pain?
Ran into the same issue. Some digging in AX.php got me a working start. Haven't looked for any bugs, nor tested beyond basic, nor tested with anyone other than Google. This is not pretty: needs error handling, etc. But this should get you started. Will post an update if I have something robust...
First to throw ...
// oid_request.php
// Just tested this with/for Google, needs trying with others ...
$oid_identifier = 'https://www.google.com/accounts/o8/id';
// Includes required files
require_once "Auth/OpenID/Consumer.php";
require_once "Auth/OpenID/FileStore.php";
require_once "Auth/OpenID/AX.php";
// Starts session (needed for YADIS)
session_start();
// Create file storage area for OpenID data
$store = new Auth_OpenID_FileStore('./oid_store');
// Create OpenID consumer
$consumer = new Auth_OpenID_Consumer($store);
// Create an authentication request to the OpenID provider
$auth = $consumer->begin($oid_identifier);
// 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->addExtension($ax);
// Redirect to OpenID provider for authentication
$url = $auth->redirectURL('http://localhost:4001', 'http://localhost:4001/oid_catch.php');
header('Location: ' . $url);
... and then to catch
<?php
// oid_catch.php
// Includes required files
require_once "Auth/OpenID/Consumer.php";
require_once "Auth/OpenID/FileStore.php";
require_once "Auth/OpenID/AX.php";
// Starts session (needed for YADIS)
session_start();
// Create file storage area for OpenID data
$store = new Auth_OpenID_FileStore('./oid_store');
// Create OpenID consumer
$consumer = new Auth_OpenID_Consumer($store);
// Create an authentication request to the OpenID provider
$auth = $consumer->complete('http://localhost:4001/oid_catch.php');
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;
} else {
// Failed
}
Those ought to be the basics...
The request half is working, however I am getting failure in the Catch.
Should the line above
$auth = $consumer->complete('http://localhost:4001/oid_catch.php');
be
$response = $consumer->complete('http://localhost:4001/oid_catch.php');
Otherwise, where does the response object come from?
I am not getting returned the openid.current_url in my response to check the url with?

Categories