How to distinguish/identify users with OpenID without requesting SReg fields? - php

I've been toying with the JanRain OpenID PHP Library, mostly following along with a tutorial I found on ZendZone.
How does one distinguish between users - especially Google users, who all end up using the same OpenID URL, https://www.google.com/accounts/o8/id ?
Basically, I'm at the point where I can detect that they have an OpenID account... that they've successfully authenticated... but my app still doesn't know who they are; only that they authenticated.
To distinguish users, the tutorial uses a "Simple Registration request" to request the user's email of the OpenID provider - and then use email address to see if this is a returning user.
It wasn't working for me, and apparently won't work with some providers so I was excited when I stumbled upon a function getDisplayIdentifier.
require_once "Auth/OpenID/Consumer.php";
require_once "Auth/OpenID/FileStore.php";
// create file storage area for OpenID data
$store = new Auth_OpenID_FileStore('/wtv');
$consumer = new Auth_OpenID_Consumer($store);
$oid_response = $consumer->complete("http://example.com/oir_return");
if ($oid_response->status == Auth_OpenID_SUCCESS) {
$hopefullyUniqueUserID = $oid_response->getDisplayIdentifier(); // I assumed this would be a relatively permanent way to identify the user...
// I was wrong.
}
Unfortunately, after a couple of hours the value returned by getDisplayIdentifier changes.

Skimming the code, I think it's $oid_response->identity_url that you want. For me (albeit in DotNetOpenAuth not php-openid) that comes back as
https://www.google.com/accounts/o8/id?id=AItOawmqjknrgk6f9cNdPIVxW43GewJPa1ZW4GE
from Google, where the ID part is reproducible and hopefully unique to me. However I haven't left it a few hours to see if this changes, so apologies if this is what you already had from getDisplayIdentifier - but skimming the source it looks like it'd just use the first part, but then I'm no PHP expert.

The problem was that Google's OpenIDs are Unique Per-Domain; I had been absent mindedly alternating between http://www.mysite.com and http://mysite.com, which caused the OpenID identity url to change!

Why not simply use the OpenID URL to identify users? Consider it unique like an email address.

According to the last paragraph below, you should definitely use the identity_url attribute of the response object (granted, this is in reference to the Python library, but the implementations are very similar):
The display identifier is related to the Claimed Identifier, but the
two are not always identical. The display identifier is something the
user should recognize as what they entered, whereas the response's
claimed identifier (in the L{identity_url} attribute) may have extra
information for better persistence.
URLs will be stripped of their fragments for display. XRIs will
display the human-readable identifier (i-name) instead of the
persistent identifier (i-number).
Use the display identifier in your user interface. Use
L{identity_url} for querying your database or authorization server.
From the python-openid docs.

Related

ASP.NET authentication for custom API

I know this is a pretty discussed topic but i'm struggling in finding a solution for my case.
I have done an already working API service in ASP.NET (c# 4.5.1). My clients uses php pages to call a page.aspx on my server and sending via POST a string. This string contains an ID and a cypher message. Every user have a different key (AES 256) and, since i have the ID i get from my DB the correct key to decypher the message and do what its request contains. I also check the IP, every client have only a list of approved IPs (when they are not using the debug mode for testing)
I like this method but now i have to let my users do some purchases. I already implemented it (thank you PayPal) and it works, but i feel my security weak.
So i wanted to add some already known and already wrapped authentication system, without re-writing any of the already working and debugged code.
Since is used from lot of big internet services i thought about OAuth 2.0 (and i know nothing about it), but looks like everyone who talks about it is for creating a login that uses services like Facebook, Google, Twitter and go on.. not my case. I have my own database with my user list and i need to know with 100% security who is calling my API service.
I tried creating a new Web API 2 project (MVC.. damn) but i cannot understand if i can use for my service without rewriting the logic for API calling (and from what i saw looks like no is the answer)
So the question is: What authentication method can i use that is easy to implement without rewriting the already working code and can be usable from clients with PHP?
I was watching "ASP.NET MVC 5 Fundamentals" tutorial on Pluralsight by Scott Allen where he explains it quite nicely. But before watching that tutorial, for one App I worked on, we had a table in the database with tokens that were issues at Login. Then the client would send the token with their request. At server side, I did a custom attribute called [CheckToken] inside which I would check if the token exists in the database and if it is stil valid (not expired, etc.) I went a step further and sometimes swap the token so that even if the token gets stolen, it would not be valid for long. That way, the user does not have to keep login in all the time.

Tips for reliable OpenID with your own domain

I'm trying to build a personal OpenID-based online identity using my domain name as identifier. I want to be able to accomplish all this:
Make http://alvaro.es/ my identifier.
Be able to switch providers transparently.
Log into any third-party site that accepts OpenID.
Be able to provide personal details (e-mail, time zone, avatar...) and get prompted whether to send them or not to sites that request them.
Accept OpenID in my own (PHP-powered) sites without the need of purchasing SSL hosting.
I've read the usual doc and I've been evaluating several OpenID providers (Google, Yahoo, myOpenID... and even running my own server). The fact is that I've been using OpenID for a while and:
Providers offer very scarce documentation or none at all.
No matter what provider I choose, there are always sites where log-in fails (typically without an error message).
I have little control (or none at all) on the identifier returned by the provider.
I still can't understand how all this really works.
I'm looking for general advice but I understand that can be subjective so I'll make a few specific questions.
So far, I'm trying out myOpenId as provider and LightOpenID as consumer. My questions are:
My URL provides an HTTP header:
X-XRDS-Location: http://kalvaro.myopenid.com/?xrds=1
... and the following HTML tags:
<link rel="openid.server openid2.provider" href="http://www.myopenid.com/server">
<link rel="openid.delegate openid2.local_id" href="http://kalvaro.myopenid.com">
Is it correct? Is it enough?
myOpenID provides Your Domains, a feature to register your own domain name but I haven't dared to test it (it needs changes to the DNS) and the configuration form suggests I have to choose between http://openid.alvaro.es/username and http://username.alvaro.es/ as identifier (not http://alvaro.es/). However, Stackoverflow still reports alvaro.es as my identifier without this feature. Do I need to use it?
When implementing LightOpenID, I match the local user against $openid->identity (where $openid is the instance of the LightOpenID object). This attribute appears to be the URL supplied by the user. Is it correct?
Are there more adequate providers or consumer libraries than the ones I chose?
It is correct. It is more than enough. While providing an X-XRDS-Location is a good thing, as it sepeeds up the discovery process, it isn't sctrictly necessary.
As far as I understand it, "Your Domains" is useful when you want to have multiple accounts in your domain. Anyway, you don't need to use it at all.
It is correct. The url is also called a Claimed Identifier, i.e. what the user claims to be.
As the author of LightOpenID, my answer is obvious and possibly biased -- I've created it, because I couldn't find a good, existing library.
Other things you might want to know:
Delegation won't work with Google, and any other provider who uses select_identifier (i.e. each account has the same url, and then the provider asks you for your login).
Your delegation, as shown in 1., will let you switch providers transparently and log in to any site that supports OpenID, just as you want.
As for the personal details, it depends completely on the provider, whether it sends them or not, what kind of personal information it supports, etc.. For example, Google doesn't let you choose what to send, only whether to send something (and everything the website claims to require) at all.
Some implementations are buggy and indeed fail. Try logging in for a second time, it works sometimes.
The identifier returned by your provider shouldn't matter if you use delegation. The website you're logging into should use your claimed identifier.
As for how the openid works, see some answers to that question on SO.

Creating a OpenID Provider in PHP

I have an existing website that I want to turn into an OpenID provider. All my user accounts are stored in a mysql table.
I figured since an OpenID is represented as a URL, I am going to do something like: http://login.mydomain.com/username
I've setup a subdomain, and created an htaccess that redirects all URLs to /login.php?username=[username]
The way I see it, and tell me if I'm wrong, someone goes to let's say StackOverflow, they enter http://login.mydomain.com/myUsername. They get to a page on my server that asks for their password (since I already know their username), I check that it matches, and return the key?
People online recommended using Zend_OpenId_Provider. I've been reading their documentation (http://framework.zend.com/manual/en/zend.openid.provider.html), but I find it very confusing. They have no real world example where the user login/password are stored in a database.
I've also seen php-open-id (http://github.com/openid/php-openid), but no help there either.
It seems to be a pretty common thing to do. Is there a tutorial out there or an example I can easily adapt?
As you tagged this question with zend-framework I think you want to implement this with ZF.
Look at the constructor of the Zend_OpenId_Provider
public function __construct($loginUrl = null,
$trustUrl = null,
Zend_OpenId_Provider_User $user = null,
Zend_OpenId_Provider_Storage $storage = null,
$sessionTtl = 3600)
The important one is the $storage parameter.
In the example on http://framework.zend.com/manual/en/zend.openid.provider.html they do not pass any parameters. That means by default the Zend_OpenId_Provider_Storage_File provider is used. Again this one would store per default in files in your TEMP directory (/tmp on Linux).
Basically the example should be fully functional. You could register some more users by calling $server->register($someid, $somepassword);
But as it stores accounts per default in the temporary directory, you should replace that line by something like this (if it is okay to store accounts in files):
$dir = "/var/lib/myopenidusers";
mkdir($dir);
$server = new Zend_OpenId_Provider(null, null, null, new Zend_OpenId_Provider_Storage($dir) );
Now, if you prefer to store your users in a database you have to implement your own Provider_Storage.
Have a look at the abstract class abstract class Zend_OpenId_Provider_Storage. This are the methods you have to implement.
I tried everything listed here, Community ID, simpleid, janrain, etc, along with all those that claim to be providers from OpenID Wiki / Libraries and failed. I then stumbled across Prairie and got it running in about an hour. A little more work of changing the queries in index.php and login.php and I was getting it to work against my user table.
You can try phpMyId. See the demo from http://phpmyid.com/. Every details about phpMyId can be found at http://siege.org/phpmyid.php.
You can try JanRain Engage (http://www.janrain.com/products/engage). It is a simplified interface for OpenID integration with web applications. The free version should be good enough for all practical purposes.
We use: http://source.keyboard-monkeys.org/projects/show/communityid
From their website:
"Community-ID is an OpenID implementation in PHP which is OpenID 2.0 compliant. Community-ID is build to 100% on Open Source software and is release under the BSD license. Users can keep track of their trusted sites and manage them. The login to C-ID can be username/passowrd or a One Time Password with Yubikey. A user can have multiple profiles like with privat or business contact information.
For Community-ID administrators statistics are available to track registration of new users, authorized users per day or the number of trusted sites. Administrators can set the site in maintenance mode or send emails to all registered users.
For user data and authentication, admin can choose the default db storage, or to connect to an LDAP server. Current confirmed supported is OpenLDAP. Other LDAP servers should work also fine."
SimpleID is a small and nice to use + setup OpenID provider software. I use it myself and can't complain.

OpenID Directed Identity/Identifier Selection in PHP

I'm trying to implement an OpenID server in PHP that supports identifier selection (some call this directed identity, which is actually a more specific case of identifier selection). That is, a user can enter a generic URI as their OpenID identifier, log in, and choose what identifier to return to the OpenID consumer.
For example, if a user enters mysite.com as their indentifier, after they log in they would be prompted to return one of two identifiers to the OpenID consumer (perhaps mysite.com/myusername or mysite.com/anon-ad83f38c98b98).
The advantage of this system is that you have the option to either use a single identifier among many sites, or use unique identifiers for individual sites.
Anyway—I haven't been able to find a good tutorial on how to implement this portion of the OpenID spec in PHP. In fact, most searches led me to unanswered questions on forums or even on stack overflow. Does anyone know of a PHP library that can handle identifier selection or directed identity? If so, are there any tutorials out there explaining how to set it up? I've been playing with a few libraries that don't mention it one way or the other, but I haven't been able to get it working yet.
Any help is greatly appreciated.
The documentation is useless. Have you had a look at the Janrain libraries? They have a consumer which I have successfully implemented and also server code which I presume is implementable. Have a look at the Yadis\XRIRes and Yadis\XRI files, you may have to reverse engineer their code - that's what I had to do to figure out the consumer. I'm currently looking into implementing a server but can't find anything worthwhile yet.
http://openidenabled.com/files/php-openid/docs/2.1.3/OpenID/Auth_Yadis_Yadis.html
php-openid v2 is certainly capable. And really, how you interact with the library changes rather little when you add identifier selection. When you get your Auth_OpenID_ChecKIDRequest, you can check its idSelect method to see if it's a case for identifier selection. Then pass the selected identity to Auth_OpenID_ChecKIDRequest.answer().
The only other bit is to make sure that you advertise what the spec terms an "OP Identifier Element" on mysite.com/. If you're serving XRDS pages for your user identifiers already, this works the same way, just with a different Type URL. If you're not (you just have HTML-based discovery with link elements), you might want to look at myopenid's HTTP headers for an example.

OpenID -- getting user information?

I am wondering if it is possible to request more information besides email from Google and get the name of the user also?
Am using JanRain OpenID PHP script.
Thank you
No, it isn't possible. Google only releases the user's email address. Their server is set up to never give out any more information than that:
See their OpenID page for developers to learn more:
http://code.google.com/apis/accounts/docs/OpenID.html
Search for OpenID Attribute Exchange -- that's what you want.
basic overview
formal specification
We haven't looked at it in a while (6 months?) but it was quite rough when we did. Hopefully things have improved since then.
More resources:
http://www.google.com/search?q=openid+attribute+exchange
I normally read the manual only when truly defeated. For 3 days, I have tried different ways to fetch user attributes from those two giant OpenID providers, but only managed to fetch the "email" attribute from Google and absolutely nothing from Yahoo. And then I had to read the dreaded manual, even those vague OpenID specifications.
So why implement a standard and not fully support it? Why pretend that there is any viability to OpenID if the big parties will not cooperate with the smaller parties when it comes to information exchange.
I guess the basic sign up and sign in process wins after all... Who really needs to know about XRIs and URLs anyway?
You're not supposed to rely on any user information anyway. See if it's part of the OP's reply, and if it isn't, provide the user with a form where he can complete the required fields.

Categories