So I'm writing an internal API with Google's cloud functions and we're going to allow only authenticated internal service accounts to access that function.
We have some security issues and I was wondering if it's possible to allow for example everyone to make POST calls but limit the service accounts that can make a GET call.
Is this possible?
You can use API Gateway to set different level of security on different endpoints and different verbs.
If you want to authorize only some identities on a special verbs, you need to filter that in your code, no product allow you that out of the box (maybe Apigee but it's quite expensive).
Related
We have few micro-services that are used by a UI. Azure B2C is our auth provider. Each micro-service(API) requires an access token and needs to talk to a database for authorization. This database has role based access permission.
This is how it looks today:
With this we have two problems:
As Azure B2C do not allow adding scopes from multiple resources into one access token, we have to get multiple access tokens.
We are now at a stage where the UI need to call two or more APIs to display the data on one page.
We wanted to use GraphQL as an API Gateway. Something like this:
All the micro-services are placed inside a private vnet and only GraphQL API is allowed to talk to them. GraphQL Layer handles all authentication and authorization.
Now the questions are:
Do you see any problems with this approach?
Is it okay to use a client and secret for communication between GraphQL layer and other API's? or Is there an provision in Azure B2C that can do this validation with out GraphQL layer requesting individual access tokens?
what are the additional advantages of adding Azure API Management to this (other than logging, analytics, rate limiting etc)? Do I need to worry about SSL termination?
Option 2 looks like a good architecture.
A common pattern is for the UI to call a dedicated 'entry point' API, which then orchestrates calls to microservices in a private network - as in your second diagram.
Eg an Online Sales UI calls only an Online Sales API
This also helps to keep UI specific requirements out of microservices and keep responsibilities clean.
In OAuth terms as you say there will be a single resource - the entry point API - and you should only need a single access token.
The entry point API's token (or its claims) can then be forwarded directly to Microservices and used to identify the user there if needed.
I'd avoid getting additional tokens for microservices and just enforce authorization based on roles from your user database.
In some cases it may also make sense to also enforce rules such as 'Online Sales API not allowed to call Payroll microservice'.
Personally I would develop entry point APIs using the same technology as microservices.
I've implemented an ASP.NET Web API app as an Azure App Service. It has an App Registration, everything works as expected. I can hit the API from a browser and see all the JSON it returns. Now what I want to do is ensure that nothing except one or more applications from a set list can actually get anything from this endpoint. The applications needing access will all be custom ones in my organization/tenant. With all the flexibility and options, I'm having a very hard time determining what I need to do to lock the API down in this way.
I was envisioning having some client secrets the API knows about, and let the authorized applications supply them. Other methods would certainly be acceptable.
I'm certain this must be a duplicate question, but due to the plethora of information out there, and the myriad techniques for running applications on Azure, I can't seem to find just the right solution for my simple case.
It sounds like you have implemented interactive browser redirect-based authentication on the API.
Instead, you should implement JWT authentication on the API.
Then in Azure AD you can define permissions that can be granted to client applications.
In that way you can control which app can do what.
https://joonasw.net/view/azure-ad-authentication-aspnet-core-api-part-1
https://joonasw.net/view/azure-ad-authentication-aspnet-core-api-part-2
https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-protected-web-api-overview
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent
We have a multi-instance Saas Application:
Each of our clients is given their own instance and their own subdomain for the site.
Our application (Web app & API) is protected by Azure, currently with the ADAL javascript libraries
We also have a second API for system-level integration that needs to be protected, currently using a second 'native' azure app, but this is likely incorrect and we want to consolidate
Our application reads and writes to the Azure AD both through the AzureAD Graph API and Microsoft Graph API (including password reset calls)
We're looking at Azure AD application configuration options and want to make sure we're building the most sensible and secure Azure AD Application. Here are some of the documentation we've been looking at:
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-client-creds
https://learn.microsoft.com/en-us/azure/architecture/multitenant-identity/
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-compare
We want the application to be multi-tenant to ease configuration, and allow availability in the Gallery; but when looking into doing so we're left with some security questions.
A. Which application version to use
1) v1. Allows access to both Graph API. And as suggested by Microsoft we should use this when we're not concerned with Microsoft Accounts.
2) v2. When looking at the MS Graph API documentation it recommends using v2. Reportedly doesn't work for AzureAD Graph API? Allows the same app to be of multiple types (Web App/API and native), which we may or may not need to protect both our web api and our system api (which we're still trying to model).
B. How to manage the reply URL when our clients have different sub-domains?
I've noted the following options:
1) On the app registry, we add the reply urls for all of our customers. This seems okay because we only need to do it once, but feels odd. Is there a limit to the number of reply urls?
2) Have one reply url, but manage an external tool to route the responses to the correct instance, leveraging the state url parameter. Microsoft seems to be suggesting that in this link: https://learn.microsoft.com/en-us/azure/architecture/multitenant-identity/authenticate I'm not sure if ADAL allows us to set the state for a return subdomain url though. Is this approach common?
3) Is it possible for each ServiceProvider instance in our client's directories to configure the reply url to their own subdomain? I feel like this would be the cleanest approach, but I don't see documentation for it. It would be nice if we could set the replyURL programmatically as well.
C. How to manage authorization to the Graph APIs (AzureAD and Microsoft Graph)
I've noted the following options:
1) Use the client credential flow, with a single application key (used for all clients). As clients subscribe they will admin consent with our app to give the application permission to their directory. Of course we'd do our best to keep that key secure. But if for some reason it was compromised this would put all of our clients at risk, not just the one instance that was compromised.
2) Same as 1, but use a certificate instead of a secret key. I understand this could be a little more secure, but I don't see how it wouldn't suffer from the same issue as 1.
3) Instead of using application permissions, use delegated permissions with an admin user. This would be good, in that it inherently prevents one instance of our app from talking to the wrong directory. However changes to the administrator may interrupt service; and I think it is best audit-wise that our application is responsible for the changes it makes. (Also, do delegated permissions allow for password resetting? I know for app permissions you need to run powershell script to upgrade the application's directory role)
4) Is there some way for the service principal to generate a unique key for it's directory on creation? can this be handed back to our app programmatically? Perhaps during admin consent?
Really good questions. I'll try to answer each to the best of my knowledge, but if someone has other ideas, feel free to comment/add your own answer.
A. Which application version to use
v2 should allow you to call Azure AD Graph API. The documentation you linked shows an example of specifying Azure AD Graph scopes:
GET https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=2d4d11a2-f814-46a7-890a-274a72a7309e&scope=https%3A%2F%2Fgraph.windows.net%2Fdirectory.read%20https%3A%2F2Fgraph.windows.net%2Fdirectory.write
The main decision point if you should use v2 is: Do you need to support Microsoft accounts which are not in an Azure AD? If yes, you need to use v2. Otherwise there is no problem using v1 (well, lack of dynamic permissions).
Since you are using Azure AD Graph to modify things, I'm going to guess pure Microsoft accounts will not work for you. I would recommend sticking with v1.
v2 also has some limits: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-limitations
B. How to manage the reply URL when our clients have different sub-domains?
I could not find documentation on a limit for URLs. It could be that you can add however many you want. But I am not sure :)
If your subdomains look like this: https://customer.product.com, you can configure the reply URL as:
https://*.product.com
It will then allow any subdomain to be specified in the redirect_uri.
Though note that at the time of writing this, wildcard reply URLs are not supported in v2.
C. How to manage authorization to the Graph APIs (AzureAD and Microsoft Graph)
Using multiple keys makes no sense as they are all equal anyway :) Any of them could be used to call another tenant.
You can store the secret/certificate in an Azure Key Vault, and then use Azure AD Managed Service Identity to get it on app startup.
I would prefer using delegated permissions, but if the users of the app won't have the rights to do the things your app needs to do then that does not work.
I would just make sure it is not possible for a customer's instance to call to the APIs with another tenant id. And also make sure token caches are separated in such a way that it is not possible to get another tenant's access token (an in-memory cache on the instance would be good).
I am making a small Rest based webservice. I have used OAuth and other authentication mechanism before but never implemented one by myself. Can some one give direction on how to do this in either NodeJs or even in any other framework.
Use this. It has a lot of examples inside that repo.
Besides of that OAuth I would use some api-key auth (maby generated in your online service). And of course limit the access - protect your servers from too large traffic from a single api-key.
I am a complete beginner, and have just started learning about web development. Now I am asking myself some questions regards REST API: Does it make sense to secure a REST API with authentication? If so, what are the common ways of doing this?
I am under the impression that REST API's are precisely there because we try to enable many different users to access them. Now I would like to write a small application which makes requests to a node.js server and gets some stuff back. All via REST API.
However, I do not want others to be able to make similar requests to that server though. How would I best secure this? Am I misunderstanding something big time here?
Not authenticating the REST APIs means you are allowing everybody to hit your REST endpoints. It is a better practise to authenticate REST APIs and allow only certain users to access the APIs. The link might help you to have a start.
It is super simple: when you provide a service, most likely, you only want to allow certain, authenticated users to call that service. In other words: it is possible to have rest services that work without any kind of authentication - but is rather the exception, not the rule.
The more common approach is that, say a hotel only allows people with a key to enter rooms. Same story for services ...
And there are many ways to do that, see here for a starting point.
Authentication is important for REST APIs because you only want certain users to access your data via GET api and/or be able to make modifications to your database via POST api.
JSON Web Tokens(JWT) is the most commonly used authentication framework. Here's a very basic tutorial about how to authenticate node js API with JWT.