Via the api, can I force the user to login to reddit? - webview

I am writing a Reddit client that uses OAuth to authenticate the user. One of the features I would like to implement is the ability to use multiple accounts simultaneously. This requires the user to authorize my client on each account they want to use. The problem I'm running into is that if the user is already logged into Reddit in their browser, when I pop a browser to perform the auth, it will have them authenticate my client against their currently logged in user.
Is there a way to force the user to re-enter their credentials? I would rather not have to put some kind of disclaimer on my Add Account screen that says "Please log out of Reddit in any open browser windows".
I tried opening the Reddit login page in a WebView so the request is sandboxed, and while that worked, it gives the user access to the entire login page (including all the links that navigate to elsewhere on the site). I don't mind that experience when I'm popping an external browser, but in an embedded WebView I really just want to present a username and password box along with the OAuth validation prompt.
Note: I do kind of prefer the embedded experience because it doesn't interfere with the users existing browser cookies, I just don't like how cluttered the login page is this way and I'm not sure how to prevent the user from navigating away from login. Also, for completeness, this is a UWP app, though this problem is largely technology independent.

The problem I'm running into is that if the user is already logged into Reddit in their browser, when I pop a browser to perform the auth, it will have them authenticate my client against their currently logged in user.
It may be caused by the authorization server. If so, we can not do anything in our client app.
But if it is not the server issue, in UWP, there is a WebAuthenticationBroker class witch can help you to authorize your app to access the user info from Resource server by getting a token. You can try to use the class to implement OAuth authorization. You don't need to use the in a WebView so that you can authorize your app with multiple users if you can manage all the user with the token properly in your code logic.
See the Web authentication broker topic and the sample to learn more details.

Related

Auth0: How to enable silent authentication in Hosted Login Page?

I'm using hosted screen of Auth0. I want the following scenario to work-
Let's say I have 2 apps- app1 and app2.
One of the users signed in by providing email+password in app1.
User then navigated to app2.
Auth0 detected that the user has already signed in, so it redirects the user back to app2 WITHOUT having her signed in again.
But what I'm facing is this screen-
How can I save my user this additional click? How do I implement silent authentication? I know that you have to pass prompt=none to /authorize api, but since I'm not manually calling the api, how do I make the lock call /authorize with prompt=none?
What you want is silent SSO which is related to SSO but kind of independent.
The key is in the prompt param. This needs to be none in order for the user to not be prompted for login when he's already logged in Auth0's Authorization Server ("central SSO").
One annoying thing I found is that prompt is taken literally, so if the user is not logged in yet, he will not be prompted to login (you'd think it'd make sense to prompt the user when not logged right?).
In this case SSO will redirect to your app's /authorize with an error like "authentication required" and you'll have to handle it by redirecting the user to your /login endpoint again but passing prompt=true so that it knows that this time he'll have to pass prompt=true to Auth0's hosted login page.
To make things a bit uglier, currently passport-auth0-openidconnect seems to ignore the params you pass to the strategy unless you monkey patch one of the methods involved (I created a PR for it, don't when will be approved and/or if makes sense).
Essentially:
Pass prompt=none
If user is already logged in, he will silently be logged in your app as well
If user not logged in, user will be redirected to your app with "login required" error
In that case you'll have to pass prompt=true
I know it's a bit fiddly but I hope this helps you :)
PS: Another thing to bear in mind - I now just found out that it works perfectly when using Github as connection but when using google-oauth2 it blows up complain about the prompt param :|

Google OAuth - How to check that user has already allowed access to my application

Short description:
If a user has already granted my application OAuth access to their google profile, I want to spare them of having to press "sign in using google" button every time they land on my home page and log them in automatically.
If user has not granted access yet, I want to present them with sign in options page with "sign in using google" button.
Long description:
I am implementing Google OAuth flow as described on this link:
Using OAuth 2.0 for Web Server Applications
Just for the clarity, the flow in question is as follows:
present (client side) user with "sign in using google" button
after user presses the button, redirect them to google's OAuth 2.0 server, where they allow/deny my application to access their google profile
if user allows access, google redirects them back to my application
my application (server side) uses acquired grant to get access token
my application (server side) access user's profile using acquired access token
I want to achieve the following:
If user has already allowed my application access to their google profile before (either on current computer or some other), I want them to have an impression of being signed in to my application (using google) immediately after they navigate to my application's URL. Without having to click anything.
This is at first glance not a problem. To achieve this, I would automate steps 1 and 2 of the flow described above. User would be redirected to google oauth server automatically - without having to press "sign in using google" button - right after they navigates to application's URL. Google in turn immediately redirects user back to my application with a valid grant (again without requiring any input from the user). The rest remains the same. User would have an impression of being logged in immediately .
This approach has a problem though. If user goes to my page for the first time (not having granted my application access before), they would also be redirected to google OAuth page. But since they haven't granted access yet, and didn't press any sing in button, they would and end up staring at google oauth server page confused having no clue, what is going on.
Is there some API, by which I can detect that user has not yet granted access to my app (and I should present him with sing in button first)?
Please, if your solution would involve some API calls, point me to a HTTP/REST API, as I don't use (and do not want use) any higher level OAuth library.
Thanks.
Add "prompt=none" parameter to your initial OAuth redirect. This way google will not block if user has not logged in or has not granted your app the permissions.
See Chapter 3.1.2.1 of http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
Short summary of other possible "prompt" values:
none - will not prompt anything, redirects back with error "login_required" or "interaction_required" if silent login is not possible.
login - force the login prompt, even when user is logged-in.
consent - force the consent prompt, even if user has provided consent in the past.
select_account - present account selection prompt.

Is this SSO workflow possible?

Let's say I have the following sites: ClientSiteA.com, ClientSiteB.com, ClientSiteC.com, MainServer.com
I am distributing a software to client sites. Anyone will be able to install the software so a site can not be considered trusted. MainServer.com will contain user information.
Users will interact with the software on client sites. A user will be able to click a login link on any client site which will bring up a popup. The popup can reside on MainServer.com. When a user logs in on any client, they will be logged in on ALL client sites as well as the MainServer.com. Remember, MainServer.com contains all user information.
I've done a lot of reading on SAML and OAuth2. Can someone tell me what is possible? If it is possible, which tools/workflows should I use? If this isn't possible, can someone tell me something I can accomplish that is similar to this?
FYI - I am trying to accomplish something like what Disqus does. If you login to Disqus on any site, you are logged into all the sites.
You can accomplish this with SAML, although it will involve browser redirects not popups.
The first time use hits a protected site (ClientA) it redirects to MainServer.com. The user logs in, MainServer gives them a session and redirects them back to the service provider with a SAML authentication statement which then lets them in.
When the user then visits ClientB.com, it also redirects to MainServer.com for authentication. Because the user is already logged at MainServer it can invisibly bounce them straight back to ClientB.com with a new authentication statement. The user barely if at all notices.
The problem with the pop-up window approach is that users have to give their credentials for site A to site B. This is a big security hole if site B isn't owned and controlled by Site A. Users should only give their credentials to the site that is authenticating them to prevent them being compromised. SAML and other federated/distributed auth mechanisms were designed with that in mind. I wouldn't want to give the keys to my email account to random sites on the internet but with this method I can log into stackoverflow with my gmail account.

Soundcloud as Oauth Provider: How to make it connect only one time

I'm currently implementing an Oauth consumer service which is going to use Soundcloud as an Oauth service provider as well. But I'm having the following issue with it: Taking Facebook or Twitter example, you go there, you sign in, you fill up the permission form, and you are redirected back to your app. If you go there a second time, and given you are already sign in, you basically skip all steps and are redirected back instantly. That means, Facebook recognized that you already gave permission to that 3rd party service, so it doesn't ask your permission constantly.
And that's what's happening when I use Soundcloud. Basically everytime I redirected the user to the Soundcloud Oauth connect endpoint, the permission form always shows up, even though I already gave permission to that 3rd party service previously. I'm forced to press "connect" every single time, which is a drag from the user perspective (how many times can you give permission to the same entity). My question is: is there a parameter I can use to make soundcloud recognize/validate the previous permission from the user account to that specific 3rd party service? Or is this Soundcloud Oauth design implementation and we have to live with it?
Edit:
Maybe this wasn't clear, but each time I press "connect" in soundcloud, a new access token is being generated and delivered. Since my app uses this access token to identify its users, it doesn't work very well for me that the access token is getting updated everytime I want to log in, making me effectively "sign up" everytime. To sum it up, I want to get the previously attributed token to my account, so I can look up in my database, identify it and log him in.
I'm also looking for a solution which doesn't involve storing state in the client that might get cleaned up.
What you can do is store the user's oauth token in local storage and reuse it in future sessions. That's what happens on soundcloud.com.
A longer explanation:
When you use the Connect flow, the user is authenticated by SoundCloud (either by using username/password, Facebook Connect, or an already-existing session on soundcloud.com), and then when it is successful, your app is given an oauth token for that user. This is passed to the callback page which is registered for your app.
That token is the only piece of information needed to have the user be "logged in". Unless the token expires (by time, or by the user manually revoking it), then you can reuse that in future sessions.
I think I'm a bit confused about your application's design: where and how is the oauth token being used? I think that instead of using the token as an identifier, perhaps the user's permalink might be better? If you have the oauth token, you can find out the permalink by querying api.soundcloud.com/me.

Facebook Test User Login URL - Doesn't work after clearing cache/cookies

I have a test users page for my site which loads a simple grid of 4 buttons, which, when clicked, launch their associated Facebook test user login_url. I'm obtaining these via the PHP SDK and they work great...
Except when the cookies are cleared in Safari (mobile and desktop)... In this case, the test user login_url takes me to a Facebook login page where I'm prompted to login.
If I clear cookies and visit the plain old www.facebook.com homepage first and then navigate to my site, it works fine.
I understand that the 3rd party cookie setting would prevent me from loading this login_url successfully in an iFrame, but I don't understand why it doesn't work when I actually try to follow the link.
Is this a bug? Are Facebook test users a rather unpolished developer feature?
Disclaimer: I work for Facebook, but I am not on the Platform team, so my knowledge on this topic isn't that much more than a regular developer.
The login_url mechanism is not a full blown secure login mechanism. I would venture to guess that it switches the identity of the currently logged in user from the regular user to the test user. However, if there is no currently logged in user, it can't switch the identity, and therefore needs to ask you to login.
However, test users do have a user ID and password (which were returned as a response to the create API) that you could use to go through the standard Facebook login procedure. Note though that as far as I know, currently there is no automated method of loggin a user using the user ID/password - they are intended for manual logging in scenarios.

Resources