Azure API Management - Authentication: OAuth2 vs Certificate - azure

I would like to have your mind about an implementation. Thank you in advance for any suggestion :)
**Scenario**
I have a set of APIs. They are accessible via REST and protected by OAuth2. I have also a list of machines that needs to access them.
Question
On machine’s side, which is the best solution to access them? Should I implement a client certificate authentication or OAuth2 is a suitable solution?
**My doubts:**
In case of hundreds, thousands of machines, the certificate
management become too complex/costly?
Should I use a certificate for each machine or one certificate for more than one?
How can I deploy smartly the certificate to each machine?
I like the idea to have the mutual authentication, but I’m afraid is to heavy to maintain compared to the OAuth structure. I plan to use Microsoft Azure as cloud service.
Thanks!

I would say the important factors here are client identity and privilege:
You may have many client machines
But do they represent a single identity, eg a cluster?
And do they all have the same privilege?
By default I would aim for a solution where all client machines with the same privilege present the same credential / identity. The APIs can then authorize requests based on the client identity, provided in the access token.
The standard OAuth solution is Client Credentials flow, where clients each send a secret to the server.
If required (and supported by your Authorization Server) you can use a Mutual TLS form of Client Credentials, via the Client Assertion Profile. This usually boils down to a private key signature sent by the client, which is contained in a whitelist configured on the Authorization Server.

Related

Using ADF for REST API authentication using client certificate

We want to call a REST API endpoint of a SaaS application. i.e. system to system interaction.
We are using Azure Data Factory to call and we could see that ADF support(Web client activity) client certificate authentication.
We have the certificate with us. Added the certificate to AKV, configured ADF to use the certificate.
Question:
Do we need an app registration to be able to use?
What details do we need to send to the SaaS vendor so that they can recognize that our call is a legit call?
Are there any other steps in the process?
From the way you're describing this issue, it sounds like the SaaS isn't an application that is protected using Azure AD. In that case, the SaaS determines what credentials are suitable - likely a username and client certificate. I can't think of a reason for you to need to create an app registration. All of this said - you need to talk to the vendor to ask them what credentials are necessary for access.

Is it possible to use/forward certificate information from key credentials to a bearer token (Azure AD)

I have a scenario where I have to let external systems have access to one of our internal API's.
The security team want the externals to use client certificates as the preferred authentication method, so that basically leaves us two options:
Use direct client certificate authentication. It will give us the most control, but that will leave all the certificate handling and validation in our hands, and I'd rather not do that if I have a choice. Besides - direct client certification auth does not play well with our existing authentication methods on that API. If you turn on client certificates on the App Service, you will require a certificate on every request (and most requests on that API use cookies)
Add key credentials to the Azure AD app. We'd rather not give access directly to the app the API is registered on, so we register a OUR-APP-EXTERNAL and set up a trust relationship between the two. So the client authenticates with a certificate to the "external app", gets a bearer token and use that on our API. I'd prefer to use this solution, and it seems to play nicely with everything else.
So far so good - but I'm worrying about scaling this. We have to separate the external clients somehow (each client will in effect be different systems in different companies). One strategy is to create one AD-app per external system (OUR-APP-EXTERNAL-SYSTEM-A), but it seems cumbersome and somewhat spammy. One quick and easy solution would be to add some metadata from the client's authentication certificate (where we could just set what system this cert is issued to during creation), and add that to the bearer token.
Is this possible? Or are there other ways to handle "multi tenant" external clients?
Thanks
Consider an option of using Azure API Management for your scenario. API Management provides the capability to secure access to APIs (i.e., client to API Management) using client certificates. Currently, you can check the thumbprint of a client certificate against a desired value. You can also check the thumbprint against existing certificates uploaded to API Management.
Follow this guide - How to secure APIs using client certificate authentication in API Management
Also you can create multiple Azure AD Application for different clients and provide provide required roles to each of these Azure AD application to Azure AD Application registered to secure Internal API.
Follow this guide for this approach - Protect an API by using OAuth 2.0 with Azure Active Directory and API Management

what's the different between the OAuth 2.0 client credentials flow and Certificate credentials

I want to write a daemon service to visit customer office 365 resource by application identity, from document i found there are two ways to support it one is https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-client-creds and the other is https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials. I want to know what's the different between them and which is the beat solution to implement a daemon service.
thanks
Based on my understanding, the only difference between them is that certificate credential provides a higher level of assurance. For example, you can control the expired time of the client_assertion you generated flexibly. Even it is leaked, the damage will be minimized based on the lifetime of client_assertion.(This is only suppose that HTTPS is not security). If the shared secret was leaked, we will not able to limit it before we detect it and disable the secret.
More detail about client credentials flow, you also can refer link below:
Service to service calls using client credentials (shared secret or certificate)

Single Sign-On in Microservice Architecture

I'm trying to design a green-field project that will have several services (serving data) and web-applications (serving HTML). I've read about microservices and they look like good fit.
The problem I still have is how to implement SSO. I want the user to authenticate once and have access to all the different services and applications.
I can think of several approaches:
Add Identity service and application. Any service that has protected resources will talk to the Identity service to make sure the credentials it has are valid. If they are not it will redirect the user for authentication.
Use a web-standard such as OpenID and have each service handle it own identities. This means the user will have to authorize individually each service/application but after that it will be SSO.
I'll be happy to hear other ideas. If a specific PaaS (such as Heroku) has a proprietary solution that would also be acceptable.
While implementing a microservice architecture at my previous job we decided the best approach was in alignment with #1, Add identity service and authorize service access through it. In our case this was done with tokens. If a request came with an authorization token then we could verify that token with the identity service if it was the first call in the user's session with the service. Once the token had been validated then it was saved in the session so subsequent calls in the user's session did not have to make the additional call. You can also create a scheduled job if tokens need to be refreshed in that session.
In this situation we were authenticating with an OAuth 2.0 endpoint and the token was added to the HTTP header for calls to our domain. All of the services were routed from that domain so we could get the token from the HTTP header. Since we were all part of the same application ecosystem, the initial OAuth 2.0 authorization would list the application services that the user would be giving permission to for their account.
An addition to this approach was that the identity service would provide the proxy client library which would be added to the HTTP request filter chain and handle the authorization process to the service. The service would be configured to consume the proxy client library from the identity service. Since we were using Dropwizard this proxy would become a Dropwizard Module bootstrapping the filter into the running service process. This allowed for updates to the identity service that also had a complimentary client side update to be easily consumed by dependent services as long as the interface did not change significantly.
Our deployment architecture was spread across AWS Virtual Private Cloud (VPC) and our own company's data centers. The OAuth 2.0 authentication service was located in the company's data center while all of our application services were deployed to AWS VPC.
I hope the approach we took is helpful to your decision. Let me know if you have any other questions.
Chris Sterling explained standard authentication practice above and it makes absolute sense. I just want to put another thought here for some practical reasons.
We implemented authentication services and multiple other micro services relying on auth server in order to authorize resources. At some point we ran in to performance issues due to too many round trips to authentication server, we also had scalability issues for auth server as number of micro services increased. We changed the architecture little bit to avoid too many round trips.
Auth server will be contacted only once with credentials and it will generate the token based on a private key. Corresponding public key will be installed in each client (micro service server) which will be able to validate the authentication key with out contacting auth server. Key contain time generated and a client utility installed in micro service will validity as well. Even though it was not standard implementation we have pretty good success with this model especially when all the micro services are internally hosted.

server-to-server REST API security

We're building a REST API that will only be accessed from a known set of servers. My question is, if there is no access directly from any browser based clients, what security mechanisms are required.
Currently Have:
Obviously over HTTPS
Have HTTP auth enabled, API consumers have a Key & password
Is it neccessary to:
Create some changing key, e.g. md5(timestamp + token) that is formed for the request and validated at the endpoint?
Use OAuth (2-legged authentication)?
Doesn't matter - from browser or not.
Is it neccessary to:
Create some changing key, e.g. md5(timestamp + token) that is formed
for the request and validated at the endpoint?
Use oauth (2-legged authorization)?
Use OAuth, it solves both these questions. And OAuth usage is good because:
You aren't reinventing wheel
There are already a lot of libraries and approaches depending on technology stack
You can also use JWT token to pass some security context with custom claims from service to service.
Also as reference you can look how different providers solve the problem. For example Azure Active Directory has on behalf flow for this purpose
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-on-behalf-of-flow
Use of OAuth2/OpenID Connect is not mandatory between your services, there are other protocols and alternatives and even custom. All depends in which relationships are services and either they both are in full trust environment.
You can use anything you like but main idea not to share sensitive information between services like service account credentials or user credentials.
If REST API security is main requirement - OAuth2/OpenID Connect is maybe the best choice, if you need just secure (in a sense of authentication) calls in full trust environment in a simplest way - Kerberos, if you need encrypted custom tunnel between them for data in transit encryption - other options like VPN. It does not make sense to implement somthing custom because if you have Service A and Service B, and would like to make sure call between them is authenticated, then to avoid coupling and sharing senstive information you will always need some central service C as Identity provider. So if you think from tis pov, OAuth2/OIDC is not overkill
Whether the consumers of your API are web browsers or servers you don't control doesn't change the security picture.
If you are using HTTPs and clients already have a key/password then it isn't clear what kind of attack any other mechanism would protect against.
Any compromise on the client side will expose everything anyway.
Firstly - it matters whether a user agent (such as a browser) is involved in call.
If there are only S2S calls then 1 way SSL HTTPS (for network encryption) and some kind of signature mechanism (SHA-256) should be enough for your security.
However if you return sensitive information in your api response, its always better to accept 2 way ssl HTTPS connections (in order to validate the client).
OAuth2 doesn't add any value in a server to server call (that takes place without user consent and without any user agent present).
For authentication between servers:
Authentication
Known servers:
use TLS with X.509 client certificates (TLS with mutual authentication).
issue the client certificates with a common CA (certificate authority). That way, the servers need only have the CA certificate or public key in the truststore, and new client certificates for additional clients/servers can be issued without having to update the truststores.
Open set of servers:
use API keys, issued by a central authority. The servers need to validate these keys on each request (and may cache the hashes of the keys along with the validation result for some short time).
Identity propagation
if the requests are executed in the context of a non-technical user, use JWT (or SAML) for identity propagation of the user principal and claims (authorize at security proxy/WAF/IAM, and issue JWT signed by authentication server).
otherwise the user principal refers to the technical user and can can be extracted from the client certificate (X.509 DName) or be returned with a successful authentication response (API key case).

Resources