I am designing a web-based back-end for an online service. The service could support web based portals and mobile apps as front end.
But I am stuck on how to support third-party, i.e untrusted, web sites as front end. In fact the same issue exists with mobile apps, though maybe to a lesser degree.
Briefly the issue is that authentication and authorization should happen at the back-end, and the question is how to ensure that a middle-tier or web portal does not save a user's secret credentials or through some other means can pose as an end user and perform operations that the user is not requesting!
I need to be able to authenticate the end user at the back end and I've currently got a working proof-of-concept, and the registration and authentication processes for this are as follow:
- New user connect to public registration page.
- Maybe Include JS to generate a public/private key pair?
- Authorize access to Oauth provider for basic profile info.
- Retrieve user details and populate profile.
- User supplies additional info (eg contact number, recovery email address) and their public key to complete the registration process.
And then the Authentication process for a returning user would be something like:
- Application signs request with user's private key.
- Application attaches user's Identification (user-id / open-id / etc) to the request.
- Application posts the request to the API (back-end).
- API checks that request is authenticated for the specified user (verifies signature)
- API checks that requests is authorized.
- API processes request and builds response.
- API encrypts response using user's public key.
- API attaches some basic information (eg API version and request-identifier) to the response.
- API returns the response in the user's HTTPS session.
As far as I can tell the problem comes in at step 4. The Application could submit the request to anywhere, eg a third party web site that adds benefits such as formatting and advanced functions. But this means the middle tier wil submit multiple queries to the back end on behalf of the end user, build the response, and return that page or report to the user.
By the way I am hoping to leverage two specific benefits from using openid / oauth (which I have not yet got working in my proof-of-concept implementation)
a. Make the registration process easy - user does not need to remember a new password and does not need to fill in all their details, just the bits the application need that is not supplied by Google+ and friends.
b. I do not need to deal with forgotten passwords / password resets in 99% of cases. As long as the user have access to their open-id account they can regain access to the service. When connecting from a new device, eg a second PC/tablet/whatever, the application creates a new public/private key pair and the openid provider party gives access to the user's profile. If the user switches to a new openid provider he can use the recovery email address to link a new openid URI to his profile on the system.
On the other hand I'm not looking to integrate with other more advanced features of the openid providers at this stage. I really just want a third party to handle the leg-work of identifying users and managing their passwords.
The problem is that the user registers with the back-end through an interface that may not be trusted. A bad middle tier may potentially substitute a user's public key for a public key that they control the private key for. How do I design for this kind of situation? Do I disallow third-party interfaces to the back-end completely (I would prefer not to be involved with the apps and web sites, though I will implement a reference application)