Users and OAuth2 Authorization server migration

Hello to everyone,

I would like to migrate a REST API and an OAuth2 Authorization server backed by a MySQL database to Couchbase, using Sync Gateway to sync all data from and to mobile apps.
In the current system, users can login using their username, email or phone number.
Every user have an username, which identifies them.

Question 1: Where can I store these information with Sync Gateway?
I read from documentation that I need to write a custom authentication service that runs on the same server as Sync Gateway (so it can connect to the Admin API). This is fine, except for all users registered with a phone number, because the _user model cannot save it, and as far as I know there isn’t a configuration for adding properties to sync gateway user.

One solution I thought is to create from Admin API a document for each user that will be always private, containing private informations like: email, phone number, firebase tokens (for notifications) etc.
When the user try to login (ie with his phone) , the authentication service find the username from this view first, then try to create a session with his user.
Anyone have a better idea?

Question 2: How can I validate the user password?
From Admin API I can create sessions without specifing the user password.
From Public API I can create a session sending username and password, but the cookie is set in the response header and not retrieved by json (I’m making the request from my authorization service).
There is an hidden configuration or Admin API call to check only if the user password is correct? Any workaround?

Question 3: OAuth2 authorization server, how can I migrate it?
The current web app and the mobile apps uses a token based authentication. External clients are using the Authorization Code Grant Type to login on the system (Exactly like Facebook Login).
However, Couchbase Sync Gateway uses a session based authentication, so there are a lot of differences.
Obviously, I need to maintain the service for all external clients, but the only possible solution that i can find is:
Use the old oauth2 server application, editing the database connection so it use the Admin API to connect with Couchbase Sync Gateway. Then create a new API service that wraps the token authentication, find the user connected to it and using Admin API acting in his behalf.
I don’t like this approatch because:

  1. I don’t know if acting in behalf of a user is possibe and creating a session token for each request is unmaintainable.
  2. The maintenance work increases, adding couchbase and not removing the old system (We want to change to Coucbase for reducing webservice maintenance).

So there is another way to migrate this kind of authorization server? Anyone have done this migration before?

Any help is appreciated

I think this is the right way to store extra user info.

you can call admin API from your authorization service by set ttl property so the session can valid
rather than one day.
but if you call public API ,the session is valid only one day.

“validate the user password” should be authorization service’s responsibility.

FYI

Thank you for your help!

Regarding the oidc configuration:
Configuring the application need to specify a client_id, but the authorization server uses much more than a client id. This is because users can become “developer” and create projects, which can have multiple clients (exactly like google cloud console), so if the only access to data is couchbase the Sync Gateway configuration would need to be updated every time a developer create a new client.
For the official applications configuring the openid provider is perfect, but for external clients that connect to the system is a nighmare. What are the alternatives for external clients?
I can only think about a REST API only for external clients, but this returns back to the Question 3.

About user access data
Using an oidc provider as a default configuration for register/authenticate users doesn’t mean the user access informations are stored in two systems?
Currently the Authorization server and the REST API share the same database, where the auth server can check if the password sent is correct and the API let the user change his password. The same mechanism is applicable to email and phone number.
So should I keep the Authorization Server (with his MySQL database) separate, using a changes feed method to keep the two databases in sync, or you suggest to migrate the MySQL database of the authorization server on Couchbase? In the second case, it is better to use the Sync Gateway or connecting directly to the Couchbase Server via the SDK? Most important: sharing the same bucket or creating another bucket only for the authorization server?

I think you should store user basic info into 2 systems. in Sync Gateway, you should keep basic user info sync.

if you want to use sync gateway to sync data with mobile, you should not use SDK directly to the Couchbase Server, unless you use SG 1.5 above

After some researches, I end up discarding the use of openid connect, because that will use the proprietary authentication system as external, while it’s not.

At the end the new System structure that I thought is composed in this way:
Sync Gateway:
Used directly from the official applications, like web, ios and android app.

Custom Authentication application
That will create users and authenticate them.
Tecnically it will have an API for login, registration and some other endpoints like email or phone verification.
Internally will use the Sync Gateway Admin API to communicate with storage.
Registration and login will return the sync gateway session, which will be stored as a cookie in the user browser.

OAuth2 authorization application
Will be used only for external clients for token creation.
In authorization code and implicit grant page, the current logged user will be checked using the cookie. (This means that the oauth2 server and the custom authentication application must share the same domain).
It will have a different database from Sync Gateway, that could be MySQL or another bucket in the couchbase server.

Changes feed application
Will be used for business logic and User sync with the OAuth2 Authorization application.

Custom API for external clients
Will use token for checking user authentication and scopes.
In case of user authenticated, a new Sync Gateway session will be created using the Admin API, and stored on the oauth2 application database for future requests.
Then the request will be sent to the Sync Gateway Public API, and the response will be returned.

With this configuration:

  • Business logic will be moved into the changes feed
  • Data validation will be managed with the sync function of the gateway
  • External clients continues to use the Custom Rest API.
  • Custom Rest API will only redirect requests to the sync gateway, if the token scope is ok. This will minimize the application code.
  • Official apps will have full access at all user data.

Let me know if you think something is wrong with this structure.

ping @jens for some advise.

Sorry, I’m not an expert on this stuff (at least not anymore). @adamf? @traun?

In general the auth flow looks good to me - follows the standard custom authentication pattern.

The only piece I’m not clear on is:

Changes feed application
Will be used for business logic and User sync with the OAuth2 Authorization application.

Are you talking here about custom user profile documents, or Sync Gateway’s user docs? If it’s the former - that makes sense. If it’s the latter - SG user information isn’t included in the changes response.

In Changes Feed application I’m talking about sending to the oAuth2 Authorization database the custom user profile information like first and last name, profile picture etc.
To be practice, that informations will be used on the authorization code flow to show the current user image and user name.
But now that I’m talking about it I’m thinking that it would be unnecessary, because in that request I will check if the user is connected by looking at his SyncGateway session cookie, so I could retrieve that information directly from sync gateway with a public api request.
In that case the changes feed will only create the new user usernames into the oAuth2 server database (and update, delete it), to keep the two user base in sync.

Do you think it is unnecessary to have the user information on the oAuth2 server database? It would be better to retrieve it always from sync gateway?

One last thing, do you have some suggestion about how keep the custom API for external clients more minimal as possible?