SSO for multi region architecture - oauth-2.0

I am the design stage, so open to suggestions (even language or framework are open JAVA/NodeJS/Python Spring/Express/Django etc)
My requirements is to have a multi regional deployment of the system, where each region has its own DB and possibly its own version.
I require a single domain where the user will go to and redirected to the appropriate region, and even then some accounts will use customer's SAML IDP, and some will use our own IDP.
From the user's perspective i thought of something like this:
he will be shown a page where he enters his email (no pw)
with that we will redirect him to the right region,
there if he is a SAML account, he will be redirected to the company's saml login page
if not, we can do simple user/pw login on our IDP
in the background
we can have an auth service with a lookup table in each region, the DB will be replicated across regions
when the user goes to app.acme.com or he will be routed to the auth service in the closest geographical region
the auth service will present him with the first login page where he will enter is email,
auth service will look the email up (by domain) and will redirect to the right auth services (if needed)
there the service will know if he is SAML or not and redirect accordingly
As far as subsequent calls, either the url will change to app-us.acme.com and will be region specific. OR maybe store a session cookie or something lie that that will help direct further calls to the right region.
I am open to different suggestions, and even more open if there is already a framework that has this out of the box

Related

Can I use a client side login for OAuth Authorization Code Flow?

All OAutt Authorization code flow examples I've seen sends the user to a specific login page provided by the IDP Server (Identity Provider Server).
https://auth0.com/docs/flows/authorization-code-flow-with-proof-key-for-code-exchange-pkce
I'm wondering can the login page be on the client itself, as in through an APP or SPA? Or is this something unsecure which I am not aware off. Thank
Usually it is standard to redirect as you say, but security also depends on the credential being used:
If a user is signing in via their Google password then your app should definitely never see the credentials and you should always redirect
If the user is signed in via a password stored at Company X, to only access data stored at Company X, and the password is not used for any other purposes, then it is less bad, since the company owns all of the assets involved
People who avoid redirecting usually end up using a deprecated flow such as Resource Owner Password Grant. I would avoid that, since it will not fare well in security reviews and restricts your future authentication options.
To be on the safe side I would recommend sticking to the redirect model, and using a login method provided by the Identity Management System vendor.
FUTURE DIRECTION
Interestingly, there is an emerging trend from some vendors to remain within the app when that makes sense. See the Hypermedia Authentication API, which may become a standard. A key characteristic of this is that the Authorization Server continues to govern security and tell the app what to do.

Using a third party site for OAuth2 / OIDC authorization code flow- understanding the final steps

I've a site which will hopefully use a third party service for logging in (through use of OAuth2 and OIDC). I understand 90% of the process involved but am failing to get what I see as the final step. I'll describe the steps as I see them here and maybe someone can help me fill in the gaps. In my set up the Resource Server and Authorisation servers are the same machine.
This is the login process as I envisage it.
User comes to my site (let's call it Site A) and clicks login
They're redirected to the authentication site (Site B) where they
input their username / password.
Assuming correct credentials they're then redirected back to Site A with an auth code.
Site A takes this auth code and in a back channel communicates with Site B
again asking to exchange the code for a token.
Site B provides an access token to Site A (not to the end user, to the server)
Site A then communicates with Site B again (Resource and Authentication servers are the same in this scenario) and gets the relevant user detail.
So the user is authenticated and we know what claims they have, however, what I don't get in the above scenario is how Site A knows who I (the end user) am.
I never logged in on Site A so presumably no cookie was set. Basically I've gone to the site, been redirected to another site, logged in there and then am redirected back to Site A but is there a cookie set at that last redirect to identify me?
I've read plenty about this online but haven't found a clear answer.
Also, am I correct in thinking that in authorization code flow that the access token never gets to the user but instead resides on the application server?
If you really want to know who the user is on SiteA, it has to be the user from SiteA's own user database. It makes sense if SiteA is not just a proxy for SiteB's API and has its own users, permissions and functionality.
To figure out who the user is on SiteA you will need to match all your SiteA's users with Auth Server's users.
Part 1. Import your existing users into Auth Server
If you control Auth Server, import all your current users into its user database. Every one of them will have Subject ID (Id on Auth Server side). Copy those IDs back to corresponding users in your SiteA's db: your SiteA's User table will have new column, for example:
userid, user_name, user_last_name, user_auth_id (new column)
if you can't import all your users, it gets complicated. The only way I can think of: you will have to log those users in twice - once into OIDC provider and once in SiteA and then associate SiteA's user with OIDC user.
Part 2. Matching the incoming user to the internal user in SiteA
In successful response from OIDC Server you will get ID Token back. It contains sub claim with Subject ID of the user. When you've got that, you will need to do a lookup in your internal DB and find a corresponding SiteA's user. If you did not find one, create a new user at SiteA (if all existing users had been imported)
Once you know who the user is, log them in to SiteA like you would normally do (give them a cookie for example).
OpenID Connect auth servers provide the userinfo endpoint, which Site A can use for getting info about the user who authorized the access token (or the authorization code). For the auth provider (Site B) to be able to do it, it needs to keep association between a token and its user. So there is no cookie for this purpose.
You are correct about the auth code flow - the access token stays at the backend - there is no need to send it to the frontend / user.
To be able to pair the tokens kept at the SiteA backend with the consequent requests from the browser, you have few options:
You can use a backend session with cookies, which is very easy, because most backend frameworks have a built-in support for it. The cookie is sent automatically with each request and the tokens can be stored in a session object. This solution may be harder to scale - if you need a cluster.
You can create your own session implementation - either by using cookies or by some identifier expected on REST API as the Authorization HTTP header value. The backend session data can be kept in some distributed storage, such as Hazelcast or database. The session identifier can be in form of signed JWT, so you can keep user info in it.

Enabling OAuth support in Square Connect

I have an application that currently integrates into my merchant account using my access token. Early discussion with neighborhood merchants indicates some positive interest. I want to integrate OAuth support so that I can try to get traction with those merchants.
Though https://docs.connect.squareup.com/api/connect/v1/#navsection-oauth has information, I seek some additional clarification.
(i) Access using https redirect-url is denied at Square Connect Authorize has an answer "By default the OAuth flow is disabled for applications which is why you are seeing the "Authorization not allowed" failure. If you wish to enable OAuth flow for your application then you need to contact Square." #SquareConnectSupport: I have sent an email to Developer#Square, please let me know what else do I do.
(ii) Here is how I think it will work - the OAuth integration (Please confirm)
User types in browser say "mysnow.com/square"
The Handler at "mysnow.com/square" allows user to type in an ID this ID is local to mysnow
Then the Handler at "mysnow.com/square" directs the merchant to https://connect.squareup.com/oauth2/authorize along with my application id, permissions and redirect url.
The handler then receives a notification code with AuthZ Code at the redirect URL previously provided.
Next the handler obtains the Access token (using the AuthZ code)
Finally, the handler then saves the ID, the AuthZ code , the relevant Access Token and the date/time stamp (when the token was obtained) as a tuple in a safe data store.
(iii) Using the Access Token
When there is need to access merchant data of given ID, then use the ID to get the Access Token. Use this Access Token to manage the permitted data (based on permission)
Renew the access token periodically.
​(iv) For testing purposes, I create few test/dummy merchants?​ Or do you have dummy merchant accounts that I can use for testing.
You can authorize up to ten merchants through the OAuth flow without approval from Square, which should be enough to get your integration running and tested. If you would like to make it more broadly available, you will need to contact Square about getting the app in the Square App Marketplace.
That looks essentially correct. The best practice for OAuth is something like this:
Merchant visits your landing page (e.g. mysnow.com/square) and clicks an action to start using your square integration.
Merchant's browser is redirected to the OAuth page (https://squareup.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&scope=LIST_OF_OAUTH_SCOPES_YOU_NEED)
Merchant authorizes your application to access their data and is redirected back to your site. In the URL is an authorization code
Your backend makes an API call to Square to exchange the authorization code for an access token. It then uses that access token to look up information about the merchant and pre-populate fields of your signup form (e.g. you can get name, email, etc)
With a partially populated signup form on your site, merchant is prompted to complete their registration with your service.
There isn't really a way to create "dummy" merchants, but you can sign up for multiple merchant accounts with the same identity information, as long as you use a different email for each one. If you have GMail, you can do "you+someword#gmail.com" and the mail will be redirected to "you#gmail.com", so you don't need to create a bunch of email accounts to have unique email addresses.

Using Desire2Learn/Valence with SSO

From the Valance documentation it looks like the user is always required to enter credentials at the D2L site. Is there a way for Valence to be used, without the user re-entering credentials, when a user is already authenticated by the originating webapplication? Is some type of SSO available?
Yes, In the typical configuration for SSO between a web app and the Learning Suite the same authentication service is used (either the Learning Suite itself, or a separate authentication service , or possibly the webapp that is calling in is also acting as an authenticator in the case of a portal). If any of these scenarios apply, SSO will work as follows:
Authentication is done within the browser so if the user is authenticated already and goes to the authentication service it will already have the session cookies associated with the authentications service. Therefore when the auth step is triggered it will be pass through -- meaning the user is not prompted for credentials (on the first use the user will be prompted to allow access to this app).
Additionally note that Valence APIs do not use session tokens that are subject to hijacking and instead uses ids and keys (http://docs.valence.desire2learn.com/basic/auth.html) that are used to perform signatures. As a result those keys are long lived. Apps do not need to reauthenticate the user to the LMS if they still have keys from a previous execution of the app (these keys will be reset in certain circumstances so callers must be prepared to respond to a reset key). As a result you would not typically reauthenticate a user to the Learning Suite every time the user has a session.
(if the above does not apply other SSO scenarios may possible)

Automating user-authorization step in OAuth

Background:
MySite.com - my website
ParentSite.com - website of a client
company (which will have OAUth
provider module on it)
MySite Module - a module which I have created which will be installed on ParentSite.com
and which will allow users of
ParentSite to be redirected to MySite (via
OAuth). I have full control over what
I do in this module. I will be displaying links that users will be clicking on and expecting to reach MySite and be fully logged-in.
My understanding of a standard OAuth setup:
Users go to a specific URL on MySite.com for OAuth login into ParentSite.com.
The MySite app retrieves an OAuth "request token" from the ParentSite.
The browser is redirected to the ParentSite.com site, asking to confirm that the MySite App is allowed to see the user's information.
The user confirms. (*)
The browser is redirected to the MySite.com, which now has an OAuth "access token" for the user.
The Client App sends a REST request back to ParentSite.com, using the OAuth access token from step 5 as authentication, requesting the user's identity information (e.g. ParentSite user ID, name, email address).
The ParentSite validates the OAuth access token and returns the user's information to the Client App.
My scenario is slightly different, the differences are:
A. The users are users of ParentSite.com and are at ParentSite.com and need to be seamlessly connected to MySite.com when they click on certain links on "MySite Module"
B. I would like the user-authorization step (step 3 and 4) to be automated, ie, no prompting of the user.
Q1: What do I have to do at "MySite Module" to enable all this? (detailed answer needed please!)
Q2: How can I automate step 3 and 4?
Ok, let me get this straight. Clicking on something in "parentsite" opens something on "mysite", "mysite" then tries to manipulate stuff at "parentsite" and therefore needs to be authorized to do so? If I am wrong, please disregard this answer.
I am also assuming that you have control over parentsite.com - otherwise I can not see a way for you to accomplish what you seem to need.
Part 1.
First of all, mysite needs a consumer key and secret.
Part 2.
Since calls to mysite are issued directly from parentsite, you can issue an access token directly within the parentsite service (you already know which user is logged in). So when accessing mysite.com - simply send it the access token and secret it needs.
Part 3.
Ok, so now mysite.com should have consumer key/secret and access key/secret and should be able to do stuff with parentsite.com.
Keep in mind that this really is outside the oAuth specification, but perfectly doable.

Resources