Office 365 oAuth verify user is member of organization - oauth

I am building a web application for a client and logging in with Office 365 is a requirement for the client. I am having a difficult time deciphering what exactly I need to do to make it so that only users with an email address belonging to their Office 365 organization can authenticate with my app using oAuth.
Is there a way to do this? Or am I going to have to implement the AD 1.0 endpoints? Being able to pull the users' groups and other enterprise-related data would be great but for simplicity's sake, all I really need to do is verify that they are apart of an organization.
How would I do this using the AD 2.0 endpoints?

The tenant id (tid) claim in the identity token would identify which organization (tenant) they belong to. But even easier than just checking the tid for every user would be to use the tenant-specific logon URL. So instead of the /common/oauth2/v2.0/authorize endpoint, use /<tenantid>/oauth2/v2.0/authorize.

Related

Bypassing using OAuth for GSuite Mails

Is there a way for me to bypass the need to use OAuth for me to send out emails using the G-Suite platform in my application
I am still able to send out using the Microsoft 365 platform but some of my clients will not move to 365 and prefer G-Suite
You can use a service account. You will need to have the admin of the domain configure domain wide delegation to an account on the domain.
Once delegation is configured you can then use your code to impersonate a user on the domain and send emails on their behalf. This is what i normally do with sa a system designed for sending email conversation mails. When a user creates a new account the system could send an email conformation email. On behalf of say noreply#yourdomain.com
Your issue is going to be with the fact that your clients are the ones who own the domain so your going to have to get the google workspace admin for your client to set this up for you.
The other option would be to use standard oauth2 and authorize a user on the domain and send emails on their behalf.
The issue with that is going to be your application will need to be verified with one of the highest protected scopes. Your app will need to go though a security audit before it is verified. Last I checked that audit will cost you $15k-75k

Using Client Credentials with Microsoft Graph OneNote API on Office 365 Business

I am building an app (HTTPS calls from LabVIEW) that will update my enterprise OneNote notebooks on Office 365 without the need for any user interaction. Hence I have opted for using the Client Credentials flow and granting Application permissions in Azure AD to my app (Read and write all OneNote notebooks) through Microsoft Graph.
I have referred to the instructions mentioned in the following pages:
https://msdn.microsoft.com/en-us/office/office365/howto/onenote-auth-appperms
https://developer.microsoft.com/en-us/graph/docs/concepts/permissions_reference
https://learn.microsoft.com/en-gb/azure/active-directory/develop/active-directory-v2-protocols-oauth-client-creds
https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service
https://developer.microsoft.com/en-us/graph/docs/concepts/onenote-create-page
I am able to get an access token from Microsoft Graph but once I try to use it to update my notebooks by making a POST call to the URL
https://graph.microsoft.com/v1.0/me/onenote/pages
I get the error:
"The OneDriveForBusiness for this user account cannot be retrieved." Code - 30108
However, I am fully able to access OneDriveForBusiness online using the same account which created the app and the tenant ID of which I used to grant permissions. Can someone please clarify if there are certain restrictions regarding the type of O365 and OneDriveForBusiness subscriptions that are necessary for my requirements? Which particular subscription or their combinations thereof should allow me to achieve the flow I need?
You cannot use /me with Client Credentials. /me is an alias for /users/{currentUserId but since you're using Client Credentials, there is a User in context for the API to map that alias to. You are effectively calling /v1.0/users/NULL/onenote/pages in this case.
You need to explicitly specify the User you want to access:
/v1.0/users/{userId or userPrincipalName}/onenote/pages

Suggest OAuth flow(grant type) or approach for below requirement

CompanyA is integrating with CompanyB where CompanyA's users will be buying devices of CompanyB.
CompanyA wants to show user's device(CompanyB) details on their app by calling
CompanyB's API on each user login.
CompanyA user is authenticated on CompanyA IAM.
CompanyA has to call register device when user tries to add an device first time.
Help me to identify the flow which i can use to query particular loggedin user's device only.
Do i need to create duplicate user account on CompanyB's IAM?
If i use client credential flow for API to API call, access token given by CompanyB is only provides access for API calls but it does not tell that on behalf of correct user only call is invoked.
Assume that CompanyA uses IdentityServer or any other provider as IAM and CompanyB uses Azure AD B2C.
Any other approach?
Please see below diagram,
You should be able to do this by making the Company B API multi-tenant in their Azure AD.
There are other options surely, this is just the first one that came to my mind.
Overview of the multi-tenant pattern
You would have to do admin consent on it to get the API's service principal in your Azure AD tenant.
The Company B API can give you an endpoint for doing this, redirecting you with the proper parameters to the authorization endpoint. How to send a sign-in request
After doing this, you should be able to then require permissions on the API from Company A API in your tenant (configured in Azure AD).
Configure a client application to access web APIs
After doing those things, your API should be able to use On-Behalf-Of grant flow to get an access token for Company B API.
Using Azure AD On-Behalf-Of flow in an ASP.NET Core 2.0 API
Company B API must be configured to accept access tokens from another issuer than their Azure AD of course.
In general multi-tenant scenarios, the issuer validation is commonly turned off.
If Company B wishes to have control over this, currently they will have to explicitly list the valid issuers.
Issuer values look like this: https://sts.windows.net/31537af4-6d77-4bb9-a681-d2394888ea26/, the GUID is your Azure AD tenant id.
The Company B API can extract the tenant id and user object id from the access token, and authorize the user to resources based on them.
I was looking at the AWS side and looks like they have something that could meet the requirements
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_federated-users.html
Was wondering if something like this exists in Azure.

Ho do I create a simple and secure SSO/Authentication Ingestion API for my website?

Background
We have created a web portal which our CUSTOMERS can use to host content for their users. Authentication is done through a login page where a CUSTOMER's user enters their email and address and password. Note: Our CUSTOMERS manages these emails. The portal works really well and serves our CUSTOMERS' needs really well. What they need now is the ability to allow our CUSTOMER to enable SSO from their website to our portal. They already know the email address of the user, as it's their customer or supplier. We are looking for the safest and easiest way to do this.
Our tech stack
It's all built on Azure and at the moment we are using ASP.NET MVC and SQL Server. Ideally, we would like to stick to this stack but we are open to any other suggestions. The website is SSL encrypted.
What I was thinking
Add Azure functions to enable a REST API. Give the CUSTOMER a unique API Key which they can use to request a unique "authenitcation_Key" from our API. The "authentication_key" should expire after 60 minutes and is unique for every CUSTOMER/user combination. When the already authenticated CUSTOMER's user clicks on the link/button to go from the CUSTOMER's website to our portal, the website gets a new "authenitcation_key" and adds it to the HTTP Header for us to consume and validate.
What are the major security concerns/risks to this approach? How can it easily be improved?
The one which you thinking to implement will take lots of time and security tests, why not to use industry proven solutions.
I would suggest you to use IdentityServer4, you easily configure this according to your need. I know you are using .NET full framework, but this will not stop you using IdentityServer4 which uses .NET Core.
Check here https://github.com/IdentityServer/IdentityServer4/
If your stack is on Azure, you may just set up an AZURE OpenID Connect server. Your CUSTOMER application can be registered as Openid Connect (or OAuth) client, each request can then send a JWT access_token to your portal, and your portal verify and accept JWT as authentication token.

How to secure a public REST API with Azure Active Directory without user interaction

I am working on a REST API that will be used by a number of clients in different organizations. To be more specific, a client application in an organization will connect to the REST API to exchange information. Multiple users can use this client application. Authentication should be handled by the client application in a way that there is not interaction with the user.
How can this be achieved with Azure Active Directory taking into account that:
I only would like to create one AD user account per organization and not per user in that organization.
A user of the client application should not be aware he is talking to my API, hence he should not authenticate.
The client application should authenticate with the AD account that was provided to the organization.
When an incoming call is received through the REST API, I should be able to identify the calling party.
The examples that are outlined here: https://azure.microsoft.com/nl-nl/documentation/articles/active-directory-code-samples/ never completely cover this scenario:
In the daemon example there is no user interaction, but then I should create a key (secret) for every organization. This seems quite complicated to handle.
In the other scenarios there is always user interaction.
Authenticating with a username and password without user interaction is only supported in .NET: http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/
Any guidance in pointing me to the right direction would be highly appreciated!
I think the question misunderstands the daemon model. In AAD, you create a single application with a single key and then a service principal is created per organization. You only need one key - and you can identify the calling organization by looking at the tid claim in the access token.

Resources