OAuth Apps on a Single Domain - oauth

My company has a website. Let's pretend that it's hosted at http://www.example.com. I have three apps that I need to build for different teams. Users will have different permissions, possibly different OAuth logins, per app. I'd like to host apps on domains like:
http://www.example.com/apps/my-first-app
http://www.example.com/apps/my-second-app
http://www.example.com/apps/my-third-app
My question is can I do this? I'm trying to understand if OAuth tokens are per domain or per app/url. Thank you for your help.

OAuth Tokens are indeed per domain / app / url.
I did read a while back you can create multiple tokens and store those in the db for the time being so that multiple users with multiple roles can use those tokens to do the things they are permitted to in one domain for instance. I cannot really remember where I read it, but once I do i'll get back to you as soon as possible

You should be able to have multiple consumer apps like that. I'm not sure providers would work however.
Each consumer has a unique client ID and secret (and usually a callback url on the provider, github say). As long as each consumer application has a unique client ID I can't see why this wouldn't work - just create 3 applications on the provider and then make you set the callback urls correctly.

Related

OAuth2: Client Credentials flow

Problem: I am currently working on making a REST Api available to clients (the client in this case is not the normal end user who orders the articles, but the client's Web Api that communicates with my system). In order to order different products in my system, each customer may have several accounts for each country separately. Authentication is done by authenticating the client's WebApi application to my system (machine to machine). So it looks like this should be done using OAuth2 Client Credentials Flow based on the article https://learn.microsoft.com/en-us/azure/active-directory/develop/authentication-flows-app-scenarios#scenarios- and-supported-authentication-flows, but I have doubts about the issue of client accounts for each country separately.
Question: This should be solved by creating a ClientId and ClientSecret for each client account per country separately or, however, one client account should be created, while the country should be sent by the client in each request to the Api or before adding the country as a scope or claim to access token.
Additionally, I am not sure if Client Credentials Flow is a good choice in this situation, so I would be very grateful for any suggestions.
CLIENTS
Ideally each client company should have a single client credential for getting access tokens. In sone cases, such as when there are different legal subdivisions, this can be extended. By default use a single value, but you need to understand your clients.
A client credentials flow between companies can involve stronger credentials if needed, such as JWT client assertions or Mutual TLS - as in this advanced tutorial.
CLAIMS
In your system you should map domain specific data needed for authorization against each client ID. This might include country specific access to products or whatever makes sense for your scenario.
This data can then be either included in access tokens at the time of issuance, or looked up when an access token is first received, then cached for subsequent requests with the same token. Step 3 of my Authorization Blog Post explains a couple of design patterns here.
API REQUESTS
How the client gets data in API requests is interesting:
Is data for all countries owned by the caller? If so let them select the data they want via a country parameter during API requests.
If the API client shoild never be able to see data for a country, that suggests that in at least some cases you need different clients per country.
SUMMARY
Define clients in terms of what makes sense for those companies. Avoid an explosion of clients in order to manage access rights for the same data owner. Exact solutions depend on your domain specific requirements. OAuth is a framework that is meant to be adapted.
If your entire existing data-model silos 'countries' by a concept of an account, then a set of credentials per account might be the easiest.
But it sounds to me that your data-model doesn't fully capture your actual business well. It sounds to me like you have a concept of a 'customer/client' that has access to one of more 'accounts', each representing a country.
So a more correct way to model this might be to structure your API so that a single API client can access all of the related accounts, and your API should perhaps be structured so that the idea of an accountId is somehow passed (usually in the URL for REST apis). For example, each API endpoint can be prefixed with /account/123.
To me this is more of a data-modelling and API architecture question than anything OAuth2-specific.

Application to Application access within the same suite of applications

Assume my company is offering 2 applications, say Mail and Calendar.
Both applications are using OAuth 2 to secure access.
Now Calendar wants to access data from Mail. If those were applications from two different vendors it would be natural for Calendar to ask the user to authorize it's access to Mail etc.
But since the applications come from the same source I'd like them to be able to share data without the user having to explicitly give permissions.
Or to put it differently: I have ID/Access/Refresh tokens for Calendar. How can I exchange them for an Access Token for Mail without bothering the user?
How can this be done in OAuth 2? I control both the applications and the Identity Provider.
The only solution that comes to my mind is for both Mail and Calendar to be the same Application, but that doesn't seem right (and has other issues, e.g. if you want to restrict someone's access to one of them). I could also implement special access outside of OAuth 2 but that is even worse.
A real world example would be Gmail and Google Calendar. They both present OAuth 2 interface to the outside world, but you don't have to allow them to talk to each other.
PS. References to white papers or cases studies would be appreciated
SEPARATED CLIENTS
By default in OAuth you would register multiple clients which get their own tokens. You would then use Single Sign On when navigating between them the first time:
Client ID: app1
Scope: openid scope1
Redirect URI: https://app1.mycompany.com
Client ID: app2
Scope: openid scope2
Redirect URI: https://app2.mycompany.com
If user consent is involved the user has more choice this way of how they grant access to their personal assets.
COMBINED CLIENT
You could potentially combine these into a single entry like this. Note that there is usually a hosting prerequisite of a single base domain in order for token / cookie storage to work:
Client ID: combinedapp
Scope: openid scope1 scope2
Redirect URIs: [https://app1.mycompany.com https://app2.mycompany.com]
PROS AND CONS
The first option is cleanest most of the time, since you avoid tokens with access to too much data. The second option can make sense for related micro-UIs that are really a single app with the same permissions.
APIs AND SCOPES
To share data across apps, companies build API endpoints. You can then have multiple apps that each use scopes representing multiple business areas. See the Scope Best Practices article as a starting point for designing authorization. Eg user logs into calendar app with scopes openid calendar mail - and therefore can get mail data also.

How to secure an API with OIDC/OAuth

I'm trying to better understand how to make use of OIDC/OAuth in securing a restful API, but I keep getting lost in terminology. Also when I research this question most of the answers are for Single Page Apps, so for purposes of this question assume the API will not be used for an SPA.
Assumptions:
Customers will access a restful API to interact with <Service>.
It is expected that customers will create automated scripts, or custom application in their own system to call the API.
Once setup it is not expected that there will be a real person who can provide credentials every time the API is called.
<Service> uses a 3rd party IDP to store and manage users.
3rd part IDP implements OIDC/Oauth and that is how it should be integrated into <Service>
Questions:
What OIDC/OAuth flow should be used in this situation?
What credentials should be provided to the customer? client-id/client-secret or something else?
What tokens can/should be used to communicate information about the "user"? E.g. Who they are/what they can do.
How should those tokens be validated?
Can you point me to any good diagrams/resources that explain this specific use case?
Am I missing anything important in the workflow?
It sounds like these are the requirements, if I am not misunderstanding you. The solution contains not just your own code and is more of a data modelling question than an OAuth one.
R1: Your company provides an API to business partners
R2. Business partners call it from their own applications, which they can develop however they see fit
R3. User authentication will be managed by each business partner, resulting in a unique ID per user
R4. You need to map these user IDs to users + resources in your own system
OAUTH
Partner applications should use the client credentials flow to get an access token to call the API. Each business partner would use a different credential for their set of users.
Using your own IDP to store users does not seem to make sense, since you do not seem to have an authentication relationship with the actual end users.
Access tokens issued to business partners would not be user specific by default. It is possible that a custom claim to identify the user could be included in access tokens - this would have to be developed in a custom manner such as via a custom header, since it is not part of the client credentials flow.
Access tokens would be verified in a standard OAuth manner to identify the partner - and possibly the end user.
DATA
Model users in your own system to have these fields, then store resources (such as orders) mapped against the User ID:
User ID (your generated value)
Partner ID (company the user is from)
External User ID (an ID that is easy for partners to supply)
Typically each partner would also have an entry in one of your database tables that includes a Client ID, name etc.
If you can't include a custom User ID claim in access tokens, partners have to tell you what user they are operating on when they call the API, supplying the external user ID:
POST /users/2569/orders
Your API authorization needs to ensure that calls from Partner A cannot access any resources from Partner B. In the above data you have all the fields you need to enable this.
SUMMARY
So it feels like you need to define the interface for your own APIs, based on how they will be called from the back end of partner apps. Hopefully the above hints help with this.

OAuth2, SAML, OpenID connect - Which one to use for my scenario?

I work for a company where we give customer (hundreds/thousands of users) access to 2 sites. One owned by a 3rd party SaaS and one owned by us.
Customers spend alot of time registering for both sites and we also spend alot of time removing accounts when customers no longer need access.
I would like users to register for Site A. After successful authentication; a user can click on a link within the site to access Site B but without the user entering credentials.
I want Site A identity to be used to access site B and its resources. I do not need site B resources to be presented on Site A site, but simply allow users to access site B if already authenticated to site A.
Users may have different roles on site B.
What is my best option? Oauth2 sounds like a good option. But will it satisfy my requirement above?
Who will manage the authorisation server? I presume Site B?
Thank you.
Two main options:
OLD TECH WITH COOKIES
Perhaps the cheapest option is to use hosting domains and have 2 apps like this:
mail.google.com
drive.google.com
Use a cookie issued to the parent domain, google.com
Cookie identifies user, to provide a user id
Rights are looked up in each app from the user id
OAUTH2 AND OPENID CONNECT
This is the option for modern apps and they are usually used together, due to being web, mobile and API friendly.
It is a big job though, including user migration, and usually involves giving users a new password. So it needs to be something your company are prepared to invest in.
The Authorization Server (AS) becomes a shared central resource and it is common to use a Cloud Provider to ensure high availability.
RELATED RESOURCES OF MINE
Initial Code Sample with Cloud AS
User Migration Blog Post

Using Azure AD to secure a aspnet webapi

I'm writing an application that will be the backend for a react website. The website is to be used by our customers, but we will fully control the permissions of the user. We have decided to use Azure AD to secure requests, but will also be exposing the API for end users to use directly if desired.
My understanding is in Azure AD I will have to create an application that will allow web based implicit authentication (for the react site), as well as a native application that will allow a dameon based application to authenticate to the API.
This I believe means I will have two audience ids in my application.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Sorry I'm just totally lost and the documentation is beyond confusing given how frequently this appears to change!
TLDR: Do I need two applicaitons configured in azure ad, and if so whats the best way to set permissions (claims). Also is oAuth 2 the right choice here, or should I look at open id?
Right away I gotta fix one misunderstanding.
Daemon apps usually have to be registered as Web/API, i.e. publicClient: false.
That's because a native app can't have client secrets.
Of course the daemon can't run on a user's device then.
Since that's what a native app. An app that runs on a user's device.
This I believe means I will have two audience ids in my application.
You will have two applications, at least. If you want, the back-end and React front can share one app (with implicit flow enabled). And the daemon will need another registration.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
Yes, ids are included only. If you need names, you go to Graph API to get them. But why do you need them? For display? Otherwise, you need to be using the ids to setup permissions. Names always change and then your code breaks.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Your thoughts for multi-tenant scenarios are correct. If you did want to implement these though, I made an article on it: https://joonasw.net/view/defining-permissions-and-roles-in-aad.
Why would you need to setup the roles in multiple apps though? Wouldn't they only apply in the web app?
If the native app is a daemon, there is no user.
Overall, I can see your problem. You have people from other orgs, who want access to your app, but you want to control their access rights.
Honestly, the best way might be to make the app single-tenant in some tenant which you control. Then invite the external users there as guests (there's an API for this). Then you can assign them roles by using groups or appRoles.
If I misunderstood something, drop a comment and I'll fix up my answer.
Azure AD is of course a powerful system, though I also find the OAuth aspects confusing since these aspects are very mixed up:
Standards Based OAuth 2.0 and Open Id Connect
Microsoft Vendor Specific Behaviour
ROLE RELATED ANSWERS
This is not an area I know much about - Juunas seems like a great guy to help you with this.
OAUTH STANDARDS AND AZURE
I struggled through this a while back for a tutorial based OAuth blog I'm writing. Maybe some of the stuff I learned and wrote up is useful to you.
AZURE SPA AND API CODE SAMPLE
My sample shows how to use the Implicit Flow in an SPA to log the user in via Azure AD, then how to validate received tokens in a custom API:
Code Sample
Write Up
Not sure how much of this is relevant to your use case, but I hope it helps a little on the tech side of things...

Resources