Azure Active Directory on-behalf-of flow in a microservices solution - oauth

I have a microservices solution with an API gateway in front of the microservices. I want authorization to happen at the microservice level. I have a SPA client using implicit flow to acquire a token and call the API. At the API i use the on-behalf-of flow to acquire a token to call the related microservice as the user. So to the microserice it appears to be the user and authorization can be performed.
My question is if I don't use on-behalf-of flow I would need to give the API gateway an app-level permission to access the microservice. If I give the API app-level service-to-service (client credential grant flow) capabilities, then I would have to rely on the gateway API to perform authorization, which seems like a really bad idea. It is also a really bad idea if another API needs to call mine in a similar scenario.
My question is this: what are some other approaches that would allow me to flow the user identity through to the microservice so proper authorization can occur?
I've seen examples of another header being used in Identity Server, but I'm not if that is done due to some lack of on-behalf-of options in Identity Server. Btw, I realize I could pass the user identity as a string, but I would be losing all the signed token benefits that provide a level of certainty that the token hasn't been tampered.

Related

What OAuth2.0 flow to use to secure my Rest API?

I have a Rest API that is used by different clients:
Browser, when using swagger
Postman, when calling API
Curl
Other HttpClients, jvm, Python and such.
I want all clients to get authenticated with Azure AD. So each of them has to have an email, authenticate itself in front of Azure AD and then pass some token to my Rest API, on the backend I will validate the token. I really don't understand which flow to use. The one that is closest to my scenario seems to be Credentials Flow but I still don't understand how it fits in.
This picture is what I am trying to achieve:
The OAuth 2.0 On-Behalf-Of flow (OBO) serves the use case where an application invokes a service/web API, which in turn needs to call another service/web API. The idea is to propagate the delegated user identity and permissions through the request chain. For the middle-tier service to make authenticated requests to the downstream service, it needs to secure an access token from the Microsoft identity platform, on behalf of the user.
Based on your scenario it is recommended to use On-Behalf-Of flow (OBO).

Can I use Resource owner password flow with SPA?

I'm trying to implement authentication/authorization in my solution. I have a bunch of backend services(including identity service) under API Gateway, "backend for frontend" service, and SPA (React + Redux). I have read about OAuth2.0/OpenIdConnect, and I can't understand, why I shouldn't use Resource owner password flow?
A client ( my backend for frontend server ) is absolutely trusted, I can simply send users login/password to the server, then it forwards them to Identity server, receives the access token && refresh token and stores refresh token in memory(session, Redis, etc), and send the access token to SPA, which stores it in local storage. If SPA will send a request with the expired access token, the server will request a new one using refresh token and forwards the request to API Gateway with the new access token.
I think in my case a flows with redirects can provide worth user experience, and are too complicated.
What have I misunderstood? What potholes I'll hit if I'll implement authentication/authorization as I described above?
OAuth 2.0 specification's introduction section gives one key information on the problem it tries to solve. I have highlighted a section below,
In the traditional client-server authentication model, the client
requests an access-restricted resource (protected resource) on the
server by authenticating with the server using the resource owner's
credentials. In order to provide third-party applications access to
restricted resources, the resource owner shares its credentials with
the third party
As a summary what OAuth wants to provide is an authorization layer which removes the requirement of exposing end user credentials to a third party. To achieve this it presents several flows (ex:- Authorization code flow, Implicit flow etc.) to obtain tokens which are good enough to access protected resources.
But not all clients may able to adopt those flows. And this is the reason OAuth spec introduce ROPF. This is highlighted from following extraction,
The resource owner password credentials grant type is suitable in
cases where the resource owner has a trust relationship with the
client, such as the device operating system or a highly privileged
application.The authorization server should take special care when
enabling this grant type and only allow it when other flows are not
viable.
According to your explanation, you have a trust relationship with client. And your flow seems to be work fine. But from my end I see following issues.
Trust
The trust is between end user and the client application. When you release and use this as a product, will your end users trust your client and share their credentials.? For example, if your identity server is Azure AD, will end users share Azure credentials with your client.?
Trust may be not an issue if you are using a single identity server and it will be the only one you will ever use. Which brings us the next problem,
Support for multiple identity servers
One advantage you get with OAuth 2 and OpenID Connect is the ability to use multiple identity servers. For example, you may move between Azure AD, Identityserver or other identity servers which of customer's choice (ex:- they already use on internally and they want your app to use it). Now if your application wants to consume such identity servers, end users will have to share credentials with your client. Sometimes, these identity servers may not even support ROPF flow. And yet again TRUST become an issue.!
A solution ?
Well I see one good flow you can use. You have one front end server and a back-end server. I believe your client is the combination of both. If that's the case you could try to adopt authorization code flow. It's true your front end is a SPA. But you have a backend you can utilise to obtain tokens. Only challenge is to connect front end SPA with back end for token response (pass access token to SPA and store other tokens in back-end). With that approach, you avoid above mentioned issues.

Need an API design pattern where I can expose the same api to background process and end clients

Our apis are being consumed by 3rd party deamon applications as well as client applications. For third party deamon application we can expose the api via the client credential oauth flow and for the client application(S) we use the implicit grant outh flow.
The challenge we are facing is that in case of the implicit grant flow the user details are fetched from the ACCESS TOKEN. But when the same api is used for the client credential flow the user details can not be fetched from the ACCESS token as it has only application specific details.
What is the the best api design approach to handle the above challenge ?
Do I need two set of api(s) one for integrating with client application and one for integrating with server application ?
Will the usage of any alternative oauth flow help ?
Refer to Authentication scenarios for Azure AD documentation, as you stated correctly user interaction is not possible with a daemon application, which requires the application to have its own identity. This type of application requests an access token by using its application identity and presenting its Application ID, credential (password or certificate), and application ID URI to Azure AD. After successful authentication, the daemon receives an access token from Azure AD, which is then used to call the web API.
The quintessential OAuth2 authorization code grant is the authorization grant that uses two separate endpoints. The authorization endpoint is used for the user interaction phase, which results in an authorization code. The token endpoint is then used by the client for exchanging the code for an access token, and often a refresh token as well. Web applications are required to present their own application credentials to the token endpoint, so that the authorization server can authenticate the client.
Hence, the recommended way is two have two version of api implemented with two different type of authentication based on your scenario.
Reference -
Daemon or server application to web API
Understanding the OAuth2 implicit grant flow in Azure Active Directory (AD)

OAuth 2.0 Flows for Microservice Architectures

I'm trying to understand how to best apply the OAuth 2.0 grant types to a microservice architecture I am working on. Here's the situatation...
I have a Single-Page Application/Mobile App acting as a client running in a web browser (browser acting as the user agent) or mobile phone. I use the Implicit Grant defined in RFC 6749, section 4.1 to authenticate a user and acquire an access token that the app uses to access some externally exposed API.
The architecture I am dealing with is a collection of microservices that call on one another. For example, consider an externally exposed API serviceA and internal APIs serviceB and serviceC. Let's say serviceA depends on serviceB which subsequently depends on serviceC (A --> B --> C).
My question is, what is the typical authorization flow for this situation? Is it standard to use Implicit Grant for the SPA to acquire an access token and then use the Client Credentials Grant defined in RFC 6749, section 4.4 to acquire an access token for the machine to machine interaction between serviceB and serviceC?
For your single page application, use the Implicit grant, which is designed for browser applications - they cannot hold any secrets and with the Implicit grant, the tokens stay in the browser (because it's in the hash part of the redirect URL).
The mobile app, take a look at the OAuth 2.0 for Native Apps, it recommends the use of the Auth code grant. It also describes implementation details for common platforms and security considerations.
There is a new grant described in the OAuth 2.0 Token Exchange RFC that would suit your needs for chained calls between services:
... An OAuth resource server, for example, might assume
the role of the client during token exchange in order to trade an
access token, which it received in a protected resource request, for
a new token that is appropriate to include in a call to a backend
service. The new token might be an access token that is more
narrowly scoped for the downstream service or it could be an entirely
different kind of token.
But I don't know whether Auth0 supports it. If it doesn't, I would probably pass the original access token from serviceA to serviceB and serviceC. The internal services could be secured at the network level too (e.g. they could called just from other services).
If serviceB and serviceC are internal and will never be called from an external client then the Client Credentials Grant would be a good candidate. As the client is also a resource server too.
You could also look at passing the same bearer token between services, providing the SPA (which requests the token initially) obtains consent for all scopes which may be used by the other services and the "audience" of the token must allow for all the possible resource servers (services).
I don't think either are best practice and there are tradeoffs with both ways.
I would honestly recommend for each backend service to implement the Authorization Grant. That is have an endpoint exposing the redirect to your provider. Then for each frontend app go to that endpoint to trigger the OAuth flow. After the flow has been completed handle the Authorization part in the callback url and return a token which will be stored on the frontend somewhere.
Hope this helps.

External API's Calling My API Secured with Azure Active Directory

If I have an API secured with Azure Active Directory, what is the flow when an external API wants to talk to my internal API?
Is this just an API to API call as normal or is this a special circumstance and needs handling a different way?
Is this just an API to API call as normal or is this a special circumstance and needs handling a different way?
The special circumstance may depend on the confidentiality of the resources served by these api(s) and the level of security your application needs. In the end it is an api to api call only.
There are two approaches you can use if Azure Active Directory (AAD) is your Identity Provider for the entire application.
Application Identity with OAuth 2.0 client credentials grant provided by AAD. The calling API makes a request to AAD token endpoint with its client id, client secret (credential) and the application id (the unique id for the callee API) to receive an access token as response. This token is used as Bearer token to call the downstream API. In this approach client id, client secret, application id that are exchanged for an access token, are static values. Some one who has access to these values may find a way to compromise application security (highly unlikely).
The second approach is Delegated User Identity with OAuth 2.0. A request is made to AAD token endpoint with client id, client secret, the access token received as part of calling the tier1 API and a special on_behalf_of parameter to receive an access token, refresh token as response. We preferred this approach as it uses a dynamic value (access token from tier1 api) and also provides a refresh token.
You can read more about these approaches here
If you do not want to use AAD, you can use asp.net built in OwinAuthenticationMiddleware to generate and validate your own access tokens. As said earlier it all depends on your application requirements and implementation details, but in the end it is an API to API call.
Hopefully this is helpful, please let me know if you have any questions.
Thank you,
Soma.
oAuth is done for loggin user to a webservice (see also reference here).
Use OAuth to give your users access to their data while protecting their account credentials.
As another webservice wants to consume one of your service best way to do so is to have another authentication method in order to authorize
Other API, I assume you are talking of machines and not users (alias humans).
So best way is to provide another auth mechanism in order to authorize machines to connect to your API in a safe way.
A simple way to do a machine connection is using a private PKI with public/private key.
A good reference for PKI : http://docs.oracle.com/javase/6/docs/technotes/guides/security/certpath/CertPathProgGuide.html

Resources