Omniauth login withouot requesting anything - ruby-on-rails

I am looking to use omniauth for user login. For security purposes I would like to request no data be requested from the provider.
I have tried:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_APP_SECRET'], scope: '', info_fields: ''
end
However when I login to facebook I am still advised that my app will receive the user's public profile. When I click "Review the info you provide" I am unable to deselect the public profile information that includes name etc.
Is it possible to receive no identifying details?

No, that is not possible.
user_profile is the most basic permission, and gets asked for automatically during login, even if you don’t specify it.
Is it possible to receive no identifying details?
Well you don’t actually want none at all, because without something to identify a user by, you would not have an actual login.
If your users might be concerned about your app invading their privacy, then I can only recommend that you explain to them in detail what data your app will get access to; and maybe also what parts of that data it will actually use. (If you only need the app-scoped user id for the purpose of identifying them in your login system, but not anything else - then you could only ask for their id. Users would have to trust you on that of course.)

Related

Using OAuth but store extra information in my own DB

I've been looking into OAuth for a while, but haven't implemented it in any of my applications yet. I'm having trouble really understanding the full concept, so I still have a few questions that I haven't found an answer to, so I hope that anyone can help me.
I want a user to be able to start my application (WP8), login to facebook / twitter / microsoft / ... .
When he gets authenticated, I want to actually save this user to my own DB so I can add some user specific stuff like preferences, posts, ... .
What do I need to save in my own DB to specify a user?
Do I need to save the token itself or is this something that will be invalidated after a while? Or do I need to specify the user's name? With other words: What can I use as a unique identifier?
And what happens when a user would authenticate with for example facebook and he deletes his account?
And one more question, would you ever allow a user to connect to an application with 2 different service providers? If so, how would you make the coupling of these 2 providers to 1 user in your own DB?
I hope my questions are clear enough!
If not, don't hesitate to ask for more information!
Kind regards,
Gert
I assume that you have your own back-end where you authenticate your own users and your WP8 application is just a client.
First, let me distinguish between a user credential and a user profile. User credential is something that validates who the user is, e.g. username/password, facebook user id supplied with a valid auth token. User profile, is what you store in your own database about the user.
You also need to distinguish between a token you use to authenticate the user and the AccessToken Facebook needs to grant you access to user's data.
So... to answer your questions:
What do I need to save in my own DB to specify a user?
Create a record with user data (like preferences, and your unique user ID), and user's login method (e.g. Facebook) and credential (e.g. Facebook's user ID). This is your user's profile.
Do I need to save the token itself or is this something that will be invalidated after a while?
You can also store the Facebook AccessToken here if you've been granted "offline access" privileges by Facebook, but that is used for Facebook's access by you... not by the user's access to your app/back-end. For user's access you could just use a mechanism similar to cookie-based authentication - it's up to you. You could use the AccessToken as a kind of a "cookie", but you would need to always check against Facebook that it's valid.
With other words: What can I use as a unique identifier?
You could treat Facebook's ID as unique (so long as you never allow another account in your user profile DB to link with the same Facebook account)
And what happens when a user would authenticate with for example facebook and he deletes his account?
It's a good idea to have users still create a username/password combination that works with you site and only rely on Facebook login for convenience. In any case, Facebook provides a "Deauthorize Callback URL" when you create an app profile on Facebook. This is called when a user deactivates your app or deletes an account with Facebook. When you receive this call, you could send your user an email when an auth link to setup a different credential so as to not lose access.
would you ever allow a user to connect to an application with 2 different service providers? If so, how would you make the coupling of these 2 providers to 1 user in your own DB?
Sure, you could do that. Say you'd want to allow a Twitter account as well. You'd need to add a Twitter user ID field to your user profile database.
Here's another tip: create an ASP.NET MVC4 project in Visual Studio - the template includes an example of how to set up a user profile database with OAuth login.
Hope it gives you the high-level overview to investigate further.

Resetting basic-authenticate-with

I am trying to do a very basic authentication. I've already tried the one ryan bates used in his screencast with bcrypt-ruby and user authentication.
For a really small project I want to use something else:
http_basic_authenticate_with :name => 'user', :password => 'secret'
I've got a global called $admin and I've got a method to set its value to false (similar to logout).
Is there a way to reset this authentication so that the user (admin) has to fill in the "login credentials" again?
Kind regards
Unfortunately in case of basic_auth the user stays logged in until the browser window is closed. If user logs in with basic_auth, the browser stores the authentication information, and sends the authentication parameters through the http headers with every request.
There is a small catch to this though:
After logging in with basic_auth, when user goes browsing though your app and goes from one link to another (e.g. from http://appdomain.com/link1 to http://appdomain.com/link2 he is really going from http://username:password#appdomain.com/link1 to http://username:password#appdomain.com/link2. The browser hides the username:password# part in you addressbar, so you do not know about it.
A dirty way to logout a user that has authenticated through basic_auth would be to create a link or redirect to http://invaliduser#appdomain.com/ that the browser does not hold authentication credentials to...
EDIT: or as an alternative redirect AND login a user into a no-privilege account that cannot view or do anything within your app through http://guest:password#appdomain.com
Hope it helped.

How do I better control how DotNetOpenAuth uses Microsoft Account (Live ID)?

I am using the new OAuthWebSecurity wrapper for DotNetOpenAuth to allow users to log in to an MVC4 application with their Microsoft Account (aka Windows Live ID).
I have registered the microsoft client:
OAuthWebSecurity.RegisterMicrosoftClient(clientId: "...", clientSecret: "...");
It is all working, and I love the simplicity of it. But how do I refine what it's doing?
After selecting to log in with their Microsoft Account, the user is taken to a screen asking them to log in:
When they log in, I want them to be able to check the "keep me signed in" box.
Microsoft then asks for them to OK my access:
But I don't actually want that much access. All I want is their name and email address. And maybe their picture. I certainly don't need or want access to their contacts and friends. This is going to scare off my users.
Where can I pass parameters to OAuthWebSecurity or DotNetOpenAuth to control this?
So the user clicks yes and all is ok. However, when they leave and come back to my site - the "keep me signed in" option should have been honored. It isn't. Instead, they see this:
I don't understand the message that says:
Because you're accessing sensitive info, you need to verify your password.
What sensitive info? The contacts/friends I didn't want to begin with? Or something else?
How can I get around these two issues to make my application more user-friendly?
You need to pass the scopes you want, you can just use wl.signin which will sign users into your application if they are already signed in to live without asking for the credentials again.
Check http://msdn.microsoft.com/en-us/library/live/hh243646.aspx

Ruby on Rails: Authlogic Facebook integration: Link accounts with user input instead of automatically using email address

I'm developing a web app in Ruby on Rails. I'm using authlogic to do authentication. My site has its own logins, but I'm hoping to also use Facebook. I tried out authlogic_facebook_connect (using Facebooker). After a lot of hiccups (the docs haven't really been fully kept up), I did get authlogic_facebook_connect to work and it's OK. The default "connect" behavior works perfectly when I'm faced with users who have never used by site before, but it results in a lot of duplicate logins for people that are using different email addresses for Facebook and for my site. Here's what I want:
When the user hits the Facebook "Connect" button (and after they go through the Facebook auth step of clicking 'Allow'), I want a box to pop up asking the user if they want to connect to a pre-existing account on my site or if they want to have an account automatically generated for them.
If they want it automatically generated for them, we're good and we proceed as normal, but if -- on the other hand -- they want to link their Facebook account to an account on my site, I actually want them to enter in their local credentials and find the correct account. In other words, I do not want my solution to automatically figure out which account looks like the right one, I want the user to do this.
Is there any gem / plugin / quick hack that will allow me to pull this off either using authlogic_facebook_connect or OAuth or something else?
--David
Someone else may be able to point you at the perfect gem for this, but I can tell you that I've worked on a similar problem and it wasn't much work to roll our own, based on the oauth2 gem.
Here's a sketch of the code/flow I use.
1) User clicks on 'Connect to Facebook' and this sends you to an action like this
def to_facebook
options = {
:redirect_uri => facebook_callback_url,
:scope => "email,publish_stream" # whatever you want to do
}
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_API_SECRET, :site => FACEBOOK_API_SITE)
redirect_to client.web_server.authorize_url(options)
end
2) User goes over to facebook and gives you all the access you want, then facebook calls the callback you specified facebook_callback_url which should take you to an action like this:
def facebook_callback
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_API_SECRET, :site => FACEBOOK_API_SITE)
access_token = client.web_server.get_access_token(params[:code], :redirect_uri => facebook_callback_url)
do_my_custom_user_association(access_token)
end
Then you can specify whatever you want in do_my_custom_user_association, you should have a current_user available from authlogic if someone is logged in, so you can redirect to a flow that lets the logged in user select if they want to merge into their current account or a different one. If there's no current user, you can send them to a create account flow, with some facebook data attached.
Note that this is just a sketch, there are error cases to handle (e.g. facebook_callback will be hit with the param error_reason if the get_acccess_token fails) and I'm not recommending you do all the oauth2 interaction right in your controller, but the basic idea is there.
See http://developers.facebook.com/docs/authentication/ if any of the oauth2 interactions don't make sense.

Linking new users signed in via Facebook connect to existing accounts

I have recently implemented login to my via facebook connect. So now users have 2 ways of logging in to the site. The old way of registering an account and the new way (facebook connect).
One thing I would like to do is link a new facebook connect user account to existing accounts if they logged in the old way.
Has anyone had any success doing this?
Very good question I think and lots of people will benefit from an answer.
What you need to remember is that accounts are only linked so long as they are authorised to be linked through Facebook. What you should do is maintain a second table of linked accounts in your database so that you know who is who and if they are linked with Facebook.
You should read this integration comment, it provides a lot of useful information.
http://crazyviraj.blogspot.com/2010/01/test-cases-for-basic-facebook-connect.html
It doesn't really say how to do things, but it makes sure you tick all the boxes of what you should be doing.
ie:
Sign Up should fail if the user denies
permission to the app (category: sign
up)
Since we need access to an email
address, Sign Up should fail if the
user provides publish permission but
denies email permission (category:
sign up)
If the user provides an email address
that already exists in your system,
fail Sign Up. Make sure no YouFace
backend tables are modified (category:
sign up, 1:1 mapping) PS - when this
happens, I didn't find a way for you
to de-authorize YouFace on the
Facebook user's behalf. The user must
manually do this if they wish you use
the same account but provide a
different email address.
Accounts created using Facebook
Connect should not be able to login
using YouFace's default email/password
login system (category: sign in,
account security). PS: Since YouFace
accounts require a password and those
created using Facebook Connect don't,
make sure to insert a random password
hash into your table to avoid silly
errors
Accounts created using YouFace should
be able to sign in without requiring
to be signed into Facebook, even if
when a link to a Facebook accounts
exists (category: sign in)
Any many more
You should be asking for permanent access through fb connect authentication. Once you've done that, you'll get a token which gives your permission to access someone's Facebook information, and that token will not expire unless the user explicitly removes you from the permission list or changes his/her password.
Once you have the token, associate that token with the user / create a new field in your user table to store it.
To associate the user with a Facebook account without the user logging in, you can try to match by email. It's not 100% accurate but it's pretty good. Facebook doesn't give you email addresses in text form but you can get email hashes from FQL. Since you already know user email addresses, you can calculate the hash for all of your user emails and search through your user base for matches every time a new Facebook Connect user signs up.

Resources