SAML 2.0 without a browser - authentication

Let's say I have a system that's currently like this:
Monolithic Web App: Contains its own accounts and relies upon clients to log-in with (essentially) HTTP BasicAuth. That is, the username & password are getting passed to the server.
Thick Client: Logs-in to the above app, receives access token it uses thereafter for REST API calls.
Basically, I'd like to transform the above into this sort of system:
SAML 2.0 IdP: System of record for identities
Same Web App, minus Authentication responsibility
Thick Client: Unchanged. <-- hard requirement
So, crucially, I can't have the thick client do the standard SAML 2.0 Browser SSO redirects. Is there any solution? Essentially, I'd like the same functionality as OAuth2's password_grant, but in the SAML 2.0 world.
Doing some research, I've come across the SAML Enhanced Client or Proxy, but support seems spotty. The frustrating thing is, I have the darn credential in cleartext at the WebApp; is there some simple way to make this work?
Would the HTTP Artifact Binding do the trick?

NOTE: This question should perhaps better be asked on https://security.stackexchange.com/.
If you cannot change the thick client, then you cannot use SAML, or any form of browser-based single sign-on (SSO). It's as simple as that.
Also, your approach of expecting users to type their SSO credentials into the thick client, and then sending them through HTTP basic auth and automatically typing them into a form is insecure for several reasons:
The user's plain text password needs to be passed through several instances that should never see it, and it will probably also be stored in the thick client. Even if it is encrypted (in transit or at rest), this is less secure than the password being only stored as a hash on the IdP (and in the memory or password manager of the user).
Expecting users to enter their SSO credentials anywhere else than the login form of the IdP promotes dangerous use of credentials which can make users more susceptible to phishing.
If you are planning to use the IdP for SSO to more than one client than this one legacy thick client, you can use something like application passwords:
The user logs in to a web app using SSO (SAML)
The user creates an application password (and also has the option to revoke it)
The application password is then used with the thick client.
The "application password" can be a combination of a simple unique ID (which is entered as the "username") and a long random-generated string (which is sent as the "password"). If the thick client can store these credentials, then this approach would be somewhat user-friendly, although not as secure as true SSO.
In the long run, do consider updating the thick client.

Related

Does github (twitter, stripe & co) uses oauth for its own login?

Does github (twitter, stripe & co) uses OAuth for its own signin/signup forms?
All those authentications are cookie based, so is this regular web client basic auth or does it use some form of OAuth or xAuth ?
On login, a call to https://github.com/session (or https://twitter.com/sessions or https://dashboard.stripe.com/ajax/sessions) is made (with credentials given as formdata) that result in a 302 (or 200 for stripe) with Set-Cookie and a location to https://github.com (or https://twitter.com).
It does not seems that they use a client_id to get a code and exchange it with a token. All the OAuth dance seems striped. And the Bearer header too. So, what's going on here?
Thanks.
OAuth is a three-legged system, two-legs is sort of useless. The whole point of using OAuth is to give other services the ability to perform actions as you without needing to specifically authenticate or pass the data yourself. In the end you must still authenticate against some Auth service.
Since you are using these services as the Authentication mechanism for other sites, it wouldn't make sense to attempt to use it in your own. As part of setting OAuth, the second site redirects to the first and asked to authenticate there, which means you literally need to enter your credentials. Which means that if you are okay entering your credentials into say github, having a different authentication mechanism is useless.
OAuth allows non-github to create user accounts by trusting github with the authentication, or it allows non-github sites to make changes to github as the user once the user agrees to the interaction by logging into github to accept that policy (logging in using their credentials).
Sign in forms on github (and others websites as well) are simply cookie based.
Usually every direct login via the website through a browser is made with cookie based system , simply because isn't necessary to do otherwise.
A bit of theory
Every time you use a login form in a website you are calling an API, not necessarily intended for public use (so a private API)
When you put your credentials in the login form and push that login button , your credentials are being managed by some code in the server that permits you to authenticate against that website.
There is no need for the entire OAuth overhead here because the website has full control on the authentication mechanism and isn't necessary to externalize.
Why OAuth is different in this contest?
OAuth is a system designed to distribute the authentication system across different services / applications even from different vendors.
In OAuth there are multiple actors involved:
the client
the authorization server
the resource provider
In your case all these 3 actors are the website itself and so there is no need for a decoupling system like OAuth.

Is OAuth 2.0 redundant/unnecessary if the client is the same as the resource owner?

In section 1.1 of RFC 6749, there are four roles: resource owner, resource server, client, and authorization server.
Does OAuth become redundant or unnecessary if the client and the resource owner are the same entity?
For example, I have a closed API and a front-facing web server. (The front-facing web server would be both the client and the resource owner.) I am trying to decide whether to switch to OAuth 2 authentication instead of using the current username/password authentication method. Is there any added security for moving to OAuth 2 if the API remains closed to third-party applications? (That is, no third-parties will ever have access to the API.)
Thanks!
In the case where the Resource Owner and Client/Resource Server roles coincide OAuth 2.0 may become less relevant from a security point of view, since one of the primary objectives of OAuth not to expose primary credentials of the user to the client becomes moot. That is also the reason why the so-called Resource Owner Password Credentials grant is considered to be a legacy/deprecated flow.
However, it may still make sense to follow the OAuth 2.0 pattern for a number of reasons:
the ability to leverage a standardized protocol through stock libraries and
frameworks without relying on custom code
the fact that in your case the Resource Server is still made strictly OAuth 2.0 compliant, dealing with Clients presenting access tokens, irrespective of what the Client/Resource Owner relationship/implementation is; this would make it easier to allow for 3rd-party client access in a future scenario
the fact that you concentrate verification of user credentials on a single path between Client and Authorization Server so each of your Resource Servers don't need to be bothered by checking user credentials individually, possibly dealing with different authentication mechanisms
and perhaps most importantly, also security-wise: once the user has authenticated through the Client using his primary credentials, the Authorization Server can issue a refresh token as well as an access token; the Client can store and use the refresh token to a new access token when the old one expires; this frees the Client from storing the primary user credentials if it wants to keep accessing the API for a long period of time without requiring explicit user interaction and authentication and makes the resulting system less vulnerable for leakage/loss of user credentials since the user credentials (password) are not stored in the Clients
If you have the following issue then you should use OAuth;
Let's say you a Gmail like web mail provider. Some of your users are using a third party app which logs in into your user's account and auto replies certain emails for you. Or you are Facebook like social network web site where some of your users use a third party app which analyzes your friend networks and prints a 2D graph for you. In this case your users are giving away their usernames and passwords. How would they prevent a certain third party app accessing their account after they gave away their username and password? Simply by changing their password. Now you have another problem; other third party apps won't be able to access the user's account. Then the user have to re-give away his password to other apps he trusts. Now this is problem too because it is not user friendly. OAuth is simply a temporary password that your user gives away to a third party app developer. He can revoke it whenever he wants without changing his own password.
Other than that OAuth is unnecessary. Just use a session cookie if you are not going to have third party app developers. It is a random string stored in user side. And on the server side will have whatever you want. Just look how PHP sessions are used and stored on server side. You can define their lifespan and refresh time automatically from php.ini.

Security for "Private" REST API

I am currently developing a web application that is right now comprised of a front end which displays and interacts with the data using a REST API we have written. The only thing that will ever use the API is our front end website, and at some point a mobile app that we will develop.
I have done a lot of reading about how OAuth is the ideal mechanism for securing an API and at this point I am starting to have a good understanding of how it works.
My question is -- since I am never granting access to my API to a third-party client, is OAuth really necessary? Is there any reason it is advantageous? Furthermore, because the back end is simply the API, there is no gateway for a user to authenticate from (like if you were writing an app using the Twitter API, when a user authenticates they would be directed to the Twitter page to grant to access then redirected back to the client).
I am not really sure which direction to go in. It seems like there must be some approach halfway between http authentication and OAuth that would be appropriate for this situation but I'm just not getting it.
From my point of view, one of the scenarios that favor OAuth over other options is to work with untrusted clients, no matter if these are developed by you or a third party.
What's an untrusted client? Think from the point of who handles the credentials that grant access to your API.
For example, your web application could interact with your API in two falvors:
Your web app server side talks to your API. Your web app server is a trusted client because the credentials to access your API can only be access by whom have access to the server...You and your team. You could authenticate your web app server with a client_id and a client_secret.
You may want to make calls directly to your API from your Web app client, which runs on the end user's browser using JavaScript. The end user's browser is an untrusted client. If you were to deliver the credentials to your API down to the browser, anyone could check the JavaScript code and steal your credentials.
A third party Native App is also untrusted. A malicious developer that uses your API could save the credentials of and end user of your platform.
Your Native App is a trusted client and could manage the authentication with a simple username , password and a client id identifying your App.
How can OAuth help? OAuth Authorization code and Implicit grants can help you with this issue. These flows only work with clients that support a redirect, like a browser. And let you authenticate an untrusted client and a user against your Authorization Server to gain access to your Resource Server, your API, without exposing the credentials. Take a look at the RFC to see how it is done.
The good thing of OAuth is that it not only supports these redirect based authentication flows, but it also supports client credentials grant and user credentials grant. So an OAuth Authorization Server would cover all cases.
OAuth 2.0 originally seems like a PITA if you think about having to build a lot of it yourself, but most languages have some really solid OAuth 2.0 setups which you can just bolt in with varying amounts of fiddling. If you're using a framework like Laravel or RoR then it's barely any work.
PHP: http://oauth2.thephpleague.com/
Ruby (Rails or Grape): https://github.com/doorkeeper-gem/doorkeeper
If you don't want to redirect users as suggested in your post then ignore other comments and answers that talk about two legged flows. You can use the client_credentials grant type to have apps just provide their client id and secret in return for an access token, which is nice and easy.
I would ask how private are we talking, because if the only systems talking to it are within the backend and have no interaction with the outside world you could probably leave it wide open and just rely on the network to keep it safe (VPN/Firewall).
But if it's private in the sense of "our iPhone app uses it" then you definitely want to go with OAuth 2.0, or something like it.
2 legged OAuth is probably what you want to use. It's basically hashing a shared key, but you have the advantage of not having to write the code yourself.
Here's a related question: Two-legged OAuth - looking for information
You should use Oauth for mobile device to API layer communication.
However, there is no benefit of Oauth in this web UI layer to middle-layer access (machine to machine).
On the other hand there are some potential issues
Managing the access token expiry becomes a pain. Consider that your UI has to cache the access token across multiple nodes in a cluster. Refresh it when expired, and the fact that UI layer is negotiating security with backend will just take extra time once in a while.
In two legged Oauth (OAuth Client Credential as in v2.0) does not support any encryption. So you still need to send key and secret both to the server for getting an access token.
Backend has to implement issuing access token, refresh token, validating access token etc, without any significant benefit

Best way for a remote web app to authenticate users in my current web app?

So a bit of background, I'm working on an existing web application which has a set of users, who are able to log in via a traditional login screen with a user name and password, etc.
Recently we've managed to score a client (who have their own Intranet site), who are wanting to be able to have their users log into their Intranet site, and then have their users click a link on their Intranet which redirects to our application and logs them into it automatically.
I've had two suggestions on how to implement this so far:
Create a URL which takes 2 parameters (which are "username" and "password") and have the Intranet site pass those parameters to us (our connection is via SSL/TLS so it's all encrypted). This would work fine, but it seems a little "hacky", and also means that the logins and passwords have to be the same on both systems (and having to write some kind of web service which can update the passwords for users - which also seems a bit insecure)
Provide a token to the Intranet, so when the client clicks on a link on the Intranet, it sends the token to us, along with the user name (and no password) which means they're authenticated. Again, this sounds a bit hacky as isn't that essentially the same as providing everyone with the same password to log in?
So to summarise, I'm after the following things:
A way for the users who are already authenticated on the Intranet to log into our system without too much messing around, and without using an external system to authenticate, i.e. LDAP / Kerberos
Something which isn't too specific to this client, and can easily be implemented by other Intranets to log in
Both of your suggested options are insecure, even if you use SSL. Never pass credentials on a URL, put them in the HTTP request by using POST.
There is a standard called SAML and this can be used to solve your problem. The challenge is choosing which version to implement. I would choose SAML 2.0.
Google Apps implements a flavor of SAML 2.0 and allow you to authenticate using your intranet credentials. In the case of your application, you would be the service provider and your client would be the identity provider. As long as you implement the standard correctly you should be able to support any new client (identity provider). Here is a list of SAML implementations you might want to take a look at. If you need the client to pass over information in addition to the authentication information then SAML can facilitate this with metadata.
You will still need to implement SSL to encrypt network traffic.
I hate to answer my own question, but I hate even more a question with no answer. In the end we went with a very similar implementation of SalesForce's delegated authentication SSO implementation.
http://wiki.developerforce.com/page/How_to_Implement_Single_Sign-On_with_Force.com
Essentially the solution has a trusted site, known as the delegated authentication authority, who has a list of users who are logged into the company intranet.
When the user logs into the company intranet, and they click a link to our application, the company intranet will pass the user name and a generated token (which expires after a set amount of time) to our application.
Our application will then check if the user name is on our site, and if so, send the username / token (along with the source IP and a few other parameters) to the delegated authentication authority. If all those items match on the delegated authentication authority, it returns true and the user can log in. If it returns false the user is denied access.
We've found this system to work quite well, and even implemented a couple of extra security features like SSL, client side certificates, VPN tunnel, and even restricting the IP addresses which can access the site and the delegated authentication authority.
I know it's bad form to answer your own question but I hope this helps someone else who might be having the same problem ...

Desktop applications and authentication... Is there a list of authentication options?

Several sites, including this one, are using OpenID to authenticate their users. And of course, OpenID is a good solution to manage user accounts, simply by linking them to their OpenID account.
But are there similar solutions that could be used for desktop applications? I know there's CardSpace, where you create a custom ID card to contain your identity and optionally protect it with a pincode. But are there more alternatives for authentications on a desktop system or on systems within a local intranet environment?
And yes, I can write my own system where I keep a list of usernames and (hashed) passwords and then build my own login system but I just hate to invent my own wheel, especially when I need to keep it secure.
I would recommend that you look into the option of building an STS (using WIF, aka Geneva) and use (active) WS-federation in your windows app. Or if you can wait that long, just use Geneva Server when that is released.
We have a solution that works more or less like this:
Desktop tool prompts the user for ID/password
Desktop tool sends the ID/password over an encrypted (SSL) channel to the server.
Server initiates an HTTP request to a known URL of a login form and inputs the username and password as if they were form fields.
If the HTTP server responds appropriately, the server accepts the client as authenticated.
The target of that HTTP request should be tied to whatever single sign-on system that you use for the web application environment. In our case it happens not to be OpenID but it could be.