Google OpenID unique identifier problem - google-openid

i recently asked question which was closed down linked here.
https://stackoverflow.com/questions/3827349/how-to-use-one-openid-across-multiple-domains-closed
I did not even had time to correct myself. somebody mis interpret it, changed title, somebody else think it is not relavent and closed it. :(
The problem is with Google OpenID system. They are security freak. Which is good. but When we use their OpenID system, they provide DIFFERENT UNIQUE FEDERATED IDENTITY URL FOR SAME USER BUT FOR DIFFERENT DOMAIN. i.e. if i login in to meta.stackoverflow.com with Google openID and then I login in to something.com with Google OpenID, they two will not have same unique identifier of myself. so, when two domain merge, they can not recognize same user across domain. either they have to use their email id or some additional information. I wanted to know if using some other information with openID is secure enough ? I read that, anything apart from unique identifier ( i.e. nickname, email, dob etc ) is not secure enough for openID and we should not use it apart from casual use.

got it.
http://stackauth.com/
they are using common domain and not different domain. which explains everything.
https://blog.stackoverflow.com/2010/09/global-network-auto-login/
A blog post about it.
:)

Related

Impacts of removing OAuth 2 (solution by Facebook/Google)

I have ran to the situation where I have to remove Facebook/Google authentication option from my app. So I want to know all the pain during this process.
What about user data ? Is there any possibility to link newly created user with data from previous facebook-login-based user ?
Any other situations which I have to fix ?
Oh my God. I personally do not think that you should do that. Yes, if their users in your application that have logged in with one of these providers, then yes their data possibly could be deleted. I mean if you have stored the access tokens to retrieve information about them, then you will be fine I think. But, if you remove OAuth2.0 then your users will not be able to log in with anything else, such as local authentication, due to the fact that they have not created an account via your local authentication system, as they do not have provided a password for their account. They only gave consent to read or write data about themselves, and you only know their email or username. Last but not least, a move like will definitely harm your User Experience (UX) throughout your application and your marketing as well.
I hope that helps! Try to search about some alternatives to solve your issues.

Cross site session creation with Devise

I'm working on a project that uses sessions to manage the currently logged in user with a slight twist, there is no log in form on the actual application. Instead, another site will provide a button that should log in the user and redirect to their profile page.
For example, the customer is viewing their profile on Site A, the 3rd party application. From their profile on Site A they click on a button that should log them in to Site B and redirect to their profile on Site B, the site I'm building.
I'm a unfamiliar with the security concerns for a case like this. My initial thought is that if Site A POSTs via https the user's email address and password, then it should work just as if they were filling the form out on my site, Site B.
What security concerns am I missing here or will this just not work at all?
NOTE: The 3rd party site is basically out of my hands and I'll never convince that team to setup any sort of OAuth protocol, or at the very least its going to take unacceptably long. Plus, OAuth, at least with my understanding is method to accept requests from any number of 3rd parties. No other site except for SiteA will ever attempt to log people in.
This sounds like a typical application for an OAuth provider.
Get an overview and grasp the concept here: http://en.wikipedia.org/wiki/Oauth
There already exists OAuth Providers in Ruby, so you don't have to do everything by yourself: e.g. https://github.com/songkick/oauth2-provider.
But if you really wanna do this without, then I would let the other server generate a hash containing the users id (can be username, email, or database id), a random token, the current timestamp and then sign this using MessageVerifier. Then you can check on your server if the timestamp is within a certain range (some minutes) and if the message verifies (using the same key naturally). If so, then accept the user.
If the other site uses PHP, then you might have to rebuild the generate method in PHP. Find the source in Ruby here.

Token Authentication in Devise

I am a beginner in the world of Rails. Can someone please explain to me like I am a 2 year old. What in the world does token authentication do? Is it recommended for your app from a security standpoint or you are fine just without it???
Token authentication is usually used to create auto-signin links in your emails.
User clicks on link like http://example.com/some_page?auth_token=some-very-secret-token, which contains token and is recognized by token value.
So there is no need to remember password to unsubscribe from your site emails, for example.
Security tokens provide the "what you have" component in 2 factor / multi-factor solutions.
As talking to a two year old,
You want to get in the house. You would need a 'key' - a token that the system can identify you with.

DotNetOpenAuth / WebSecurity Basic Info Exchange

I've gotten a good number of OAuth logins working on my site now. My implementation is based on the WebSecurity classes with amends to the code to suit my needs (I pulled the WebSecurity source into mine).
However I'm now facing a new set of problems. In my application I have opted to make the user email address the login identifier of choice. It's naturally unique and suits this use case.
However, the OAuth "standards" strikes again.
Some providers will return your email address as "username" (Google) some will return the display name (Facebook). As it stands I see two options given my particular scenario:
Option 1
Pull even more framework source code into my solution until I can chase down where the OpenIdRelyingParty class is actually interacted with (via the DotNetOpenAuth.AspNet facade) and make addition information requests from the OpenID Providers.
Option 2
When a user first logs in using an OpenID provider I can display a kind of "complete registration" form that requests missing info based on the provider selected.*
Option 2 is the most immediate and probably the quickest to implement but also includes some code smells through having to do something different based on the provider selected.
Option 1 will take longer but will ultimately make things more future proof. I will need to perform richer interactions down the line so this also has an edge in that regard.
The more I get into the code it does seem that the WebSecurity class itself is actually very limiting as it hides lots of useful DotNetOpenAuth functionality in the name of making integration easier.
Andrew (the author of DNOA) has said that the Attribute Exchange stuff happens in the OpenIdRelyingParty class but I cannot see from the DotNetOpenAuth.AspNet source code where this class is used so I'm unsure of what source would need to be pulled into my code in order to enable the functionality I need.
Has anyone completely something similar?
AttributeExchange only applies to the OpenID Providers (Google and Yahoo!) and you can see the extension used in their respective source files.
I recommend against using email address as the username. Email addresses can be recycled (an account can expire or be closed/canceled and the email address can be reassigned to a new user). If this happens, your site based on email addresses would "give away" all the data of the old user to the new user. Massive privacy violation and lawsuit potentially happening there. Far better to use the Claimed Identifier for the OpenID cases, or the service provider-specific user id number in the OAuth cases, as the primary identifier in your user table. Certainly you may capture and display the email address everywhere on the web site where you would display a username so as far as the user knows that's the username -- it's just that internally you use something more precise than that.

How or when to follow redirected OpenIDs?

I'm currently implementing OpenID authentication for a website. During testing, I've noticed that Google accepts different versions of claimed Google Profile IDs, e.g.:
http://www.google.com/profiles/stefan.fussenegger
http://profiles.google.com/u/0/stefan.fussenegger/about
https://profiles.google.com/stefan.fussenegger
https://profiles.google.com/stefanfussenegger
Interestingly, the verified ID differs as well (for the samples above, same order):
http://www.google.com/profiles/stefan.fussenegger
https://profiles.google.com/stefanfussenegger
https://profiles.google.com/stefan.fussenegger
https://profiles.google.com/stefanfussenegger
Of course, this makes looking up the associated user account quite difficult, not to say impossible. Interestingly, all above IDs work for Stackoverflow. So I thought that there has to be some normalization step I'm missing in my implementation - or SO does some specialized voodoo to get things straight.
Looking at 7.2 Normatlization of the OpenID Authentication spec I found this:
URL Identifiers MUST then be further normalized by both following redirects when retrieving their content and finally applying the rules in Section 6 of [RFC3986] to the final destination URL. This final URL MUST be noted by the Relying Party as the Claimed Identifier and be used when requesting authentication.
Following redirects of claimed IDs doesn't help too much as I'm still left with two different IDs:
https://profiles.google.com/stefan.fussenegger
https://profiles.google.com/stefanfussenegger
Looking at redirects of verified IDs is much more helpful though as I always end up with this one:
https://profiles.google.com/stefan.fussenegger
Okay, looks like I should follow redirects of verified IDs, not claimed IDs.
The question now: Is it secure to follow redirects of claimed/verifed IDs, e.g. before search the DB like so:
do {
user = lookup(verifiedId)
if (user is null)
response = fetchUrl(verifiedId)
if (response.location is null) {
break # no redirect, jump out of loop, unknown user
} else {
verifiedId = response.location # use redirect location
}
} while (user is null)
return user;
If yes, I suspect that this should not only be done when looking up a user but when storing a new ID as well, right?
(If I should really follow redirect, I have another question about potential malicious redirects, but that will have to wait until I get an answer to this one. Might become obsolete anyway)
Open ID 2.0 says that during discovery,
URL Identifiers MUST then be further normalized by both following redirects when retrieving their content and finally applying the rules in Section 6 of [RFC3986] to the final destination URL. This final URL MUST be noted by the Relying Party as the Claimed Identifier and be used when requesting authentication.
So, according to this, you should take the user-supplied identifier and normalize it by following redirects & following normal URL normalization procedures.
The result is considered the 'claimed identifier' (CI). Next, you'll do the association dance and determine if this claim is true.
Note - Some providers have a 'well-known' OpenId Provider (OP) URL, for example Google. If you notice the sign-in process for StackOverflow, you can simply click the Google button instead of filling out a form. In this variant, the 'well-known' OP URL is not the users CI. The user did not provide you with a CI. You'll need to wait until you complete the authentication dance and Google tells you who the user is.
It's at this point (after receiving a successful association call-back from the OpenId Provider) that you'll have an identifier for the user. Per section 9.1 you SHALL receive either both an openid.claimed_id and openid.identity, or neither field if you're doing something fancy with extensions (I'm not very familiar with this aspect of the spec).
Now you should store the openid.claimed_id on your end - this will be the identifier unique to this user. This could be different from what the user originally supplied you. It might also be different from where you ended up (after following redirects on the user-supplied identifier). The OpenID Provider has the final say.
In regards to the security of following redirects on the user-supplied identifier. There shouldn't be an issue here. Redirects allow a user to delegate authentication to a provider of their choosing. No matter where the redirects lead you, you will end up asking that OpenId Provider to establish an association with you. When you make this request you'll supply the (normalized) claimed identifier and the provider can decide if they wish to be responsible for the claimed identifier, and they will (somehow in their infinite wisdom) authorize that the user has ownership of this claimed identifier.
Going back to Google, the claimed identifier Google will end up supplying you will look nothing like your examples above. The example they use is openid.claimed_id=https://www.google.com/accounts/o8/id/id=AItOawl27F2M92ry4jTdjiVx06tuFNA (source).
Hope that helps...
I'm using email as uniq identifier at this case. You can request it from google, see http://code.google.com/intl/en/apis/accounts/docs/OpenID.html#Parameters

Resources