Calling service B from service A for authentication and authorization - node.js

I have service Ticketing and a service Auth.
Not everyone is allowed to perform CRUD on tickets.
When a request comes to perform an action the ticket, I need to check if the user has proper right.
For that I need to communicate to service Auth which holds roles and endpoints of allowed permissions on the resource for a user.
How can I make this call?
Should I make sync call? i.e. Direct call from service A to B?
Use event bus
Or any other possible ways?
Also, there are some tables that is needed from Auth service to join with Ticketing service to fetch data.
How this issue can be solved?

Given the microservices tag, I assume Ticketing and Auth are separate microservices.
I am also assuming, based on description, that each has it's own API.
What's not quite clear, is how the user accessed the Ticketing service. Were they authenticated first (e.g. if a human user via a web application, did they login first, prior to being directed to Ticketing in some manner).
I assume a login was performed first.
An approach might be
At the point of user login (or caller if non-human) obtain the list of authorizations the user has access to via the Auth service.
Store the authorizations within the HTTP Authorization header
As each microservice is called, it then only need (synchronously) ask the Auth service to validate the list of authorizations is correct.
An appropriate technology approach is JWT.
In the scenario described above, when Auth is first called to authenticate the user/caller, the authorizations could be returned within the sub claim, or you could create your own claim to determine authorizations used.
As the user/caller moves through different microservices, a syncrhonous call to the Auth service need only be made to validate the user/caller is authorized.
Synchronous or asynchronous: regardless of direct call/event bus, if an authorization check is required, it needs to complete before the calling service takes action. Otherwise it may expose data / modify it, when the caller did not have authorization.
Joining tables: in a microservice pattern, this is not likely to be wise. Rather, obtain the data required from the Auth service via an API call and use that with the calling service (e.g. Ticketing).

Related

Azure AD | Service to service auth setup

I'm trying to use Azure AD to lock down access to authenticated users. I'm hoping someone could direct me to a setup that might fit the need here (and I feel like I must be overlooking the solution...).
We have an application that will expose various endpoints to be called by other teams in the organization. Nearly all of the consumers will be other user-less applications. (also none of these are Azure hosted/deployed services)
For auditing purposes, one of the requirements is the need to know what user (service) is calling any given endpoint.
Essentially, in the following:
We would need to be able to have Consumer 1 call My API, Consumer 2 call My API , and be able to determine inside of My API who the current consumer is.
I know with the client credentials flow, we could create multiple secrets and provide one to each consumer. However from the generated token, it appears that these are essentially both tokens on behalf of the Service Principal (so no way to know who the call is coming from).
I'd also looked into the ROPC flow, but I think am running into issue since we are using ADFS with our on prem AD servers.
Any easy button I'm overlooking? (fingerscrossed)
Please allow me to share my humble opinions here.
Firstly, access token is used for calling api which contains the information that if the token has correct scoped for the target api. And Id token contains the user informaion.
So if the Consumer1 and Consumer2 are on behalf of application itself, then it can't add user information within the access token and there's no id token for it. In this scenario, I think what you can do is adding an identifier into the request along with the access token, then your api application can both check if the token is illegal and which Consumer sends this request. This scenario used client credential flow to generate access token.
If the Consumer1 and Consumer2 are on behalf of users, or they are application but the request calling your api application can get the current user information, then you may send id token along with access token, or just send the user id as an identifier. This scenario may need users to sign in, so maybe auth code flow is better then credential flow.

Is it possible to utilise Open ID Connect flows for authentication but then have another source of authorization rules?

My situation is this. I have a legacy Angular application which calls a Node API server. This Node server currently exposes a /login endpoint to which I pass a user/pwd from my Angular SPA. The Node server queries a local Active Directory instance (not ADFS) and if the user authenticates, it uses roles and privileges stored on the application database (not AD) to build a jwt containing this user's claims. The Angular application (there are actually 2) can then use the token contents to suppress menu options/views based on a user's permissions. On calling the API the right to use that endpoint is also evaluated against the passed in token.
We are now looking at moving our source of authentication to an oAuth2.0 provider such that customers can use their own ADFS or other identity provider. They will however need to retain control of authorization rules within my application itself, as administrators do not typically have access to Active Directory to maintain user rights therein.
I can't seem to find an OIDC pattern/workflow that addresses this use case. I was wondering if I could invoke the /authorize endpoint from my clients, but then pass the returned code into my existing Node server to invoke the /token endpoint. If that call was successful within Node then I thought I could keep building my custom JWT as I am now using a mix of information from my oAuth2 token/userinfo and the application database. I'm happy for my existing mechanisms to take care of token refreshes and revoking.
I think I'm making things harder by wanting to know my specific application claims within my client applications so that I can hide menu options. If it were just a case of protecting the API when called I'm guessing I could just do a lookup of permissions by sub every time a protected API was called.
I'm spooked that I can't find any posts of anyone doing anything similar. Am I missing the point of OIDC(to which I am very new!).
Thanks in advance...
Good question, because pretty much all real world authorization is based on domain specific claims, and this is often not explained well. The following notes describe the main behaviors to aim for, regardless of your provider. The Curity articles on scopes and claims provide further background on designing your authorization.
CONFIDENTIAL TOKENS
UIs can read claims from ID tokens, but should not read access tokens. Also, tokens returned to UIs should not contain sensitive data such as names, emails. There are two ways to keep tokens confidential:
The ID token should be a JWT with only a subject claim
The access token should be a JWT with only a subject claim, or should be an opaque token that is introspected
GETTING DOMAIN SPECIFIC CLAIMS IN UIs
How does a UI get the domain specific data it needs? The logical answer here is to send the access token to an API and get back one or both of these types of information:
Identity information from the token
Domain specific data that the API looks up
GETTING DOMAIN SPECIFIC CLAIMS IN APIs
How does an API get the domain specific data it needs from a JWT containing only a UUID subject claim? There are two options here:
The Authorization Server (AS) reaches out to domain specific data at the time of token issuance, to include custom claims in access tokens. The AS then stores the JWT and returns an opaque access token to the UI.
The API looks up domain specific claims when an access token is first received, and forms a Claims Principal consisting of both identity data and domain specific data. See my Node.js API code for an example.
MAPPING IDENTITY DATA TO BUSINESS DATA
At Curity we have a recent article on this topic that may also be useful to you for your migration. This will help you to design tokens and plan end-to-end flows so that the correct claims are made available to your APIs and UIs.
EXTERNAL IDENTITY PROVIDERS
These do not affect the architecture at all. Your UIs always redirect to the AS using OIDC, and the AS manages connections to the IDPs. The tokens issued to your applications are fully determined by the AS, regardless of whether the IDP used SAML etc.
You'll only get authentication from your OAuth provider. You'll have to manage authorization yourself. You won't be able to rely on OIDC in the SAML response or userinfo unless you can hook into the authentication process to inject the values you need. (AWS has a pre-token-gen hook that you can add custom claims to your SAML response.)
If I understand your current process correctly, you'll have to move the data you get from /userinfo to your application's database and provide a way for admins to manage those permissions.
I'm not sure this answer gives you enough information to figure out how to accomplish what you want. If you could let us know what frameworks and infrastructure you use, we might be able to point you to some specific tools that can help.

Multiple oauth clients for the same api

I'm trying to accomplish the following scenario.
I have and API at the moment and one web app. I have also create a new oauth client on my auth server (keycloak), which follows the implicit grant. I also used jwks on my nodejs api to do the token verification.
Now I want to create an SDK that will target the same API.
The questions is how do I get the SDK to retrieve an access token from the auth server. The first thought is that I will have to create a new client oauth client on the authserver and then use the client credential flow to get the access token. However, I dont know what should the behaviour of my API be like. At the moment it used jwks against a single audience. How should it be configured to verify access tokens from multiple clients (potentially thousand of them)
If you want multiple clients to call your API they should all use the same audience, and your first level of security will work.
The audience in access tokens represents the API(s) the token can be used against.
You will then need to use something else to authorize API requests, depending on the type of client and what they are allowed to do.
Configure each type of client in your auth server so that you are in control and know who is calling the API.
You may have 1000 clients but only 4 levels of privilege - in which case only configuring 4 OAuth clients may make sense.
One OAuth option you can use is give different clients different scopes. Scopes can represent high level privileges.
If a particular client calls an addOrder operation but does not have an Orders scope you could return a 403 response.
Often though API authorization needs to go beyond OAuth checks and apply custom rules based on the end user privileges.
If you can provide more info on your scenario I could provide a more complete answer.

Where are properties (like access token) of an authorized connector inside logic app workflow actually stored?

Let's say I have Instagram connector inside my Logic App workflow, authenticated and authorized to perform actions on my behalf.
I can see this connection stored in "$connections": sections but there is no access token or anything that really makes this connection work with instagram API.
The problem here is that available Logic App actions for Instagram are way from complete and for some API calls I have to use plain HTTP action and inject my access token manually.
My question - where is in general this information is stored by Logic App (OAuth tokens and so on) and how to access it inside workflow?
This is not available. I see what you want to do - if Instagram introduced a new API Logic Apps doesn't support, it would be cool to use a generic HTTP action, but use the token Logic Apps already retrieved for auth.
This is not possible because, it would be a violation of the terms of use for third party services to make token available so end users can make any arbitrary call, since it may be abused. And this would risk all Logic Apps user lossing the ability to communicate with said service when our API key is revoked.

Secure data access to RESTful API

I figured this has been answered before, but a quick SO search didn't yield anything.
I have a private API that is locked down by an APIKey. This key needs to be passed for each request. With this key you can access any part of the API. Obviously that's pretty open. For the most part this is acceptable. However, there are cases where I want to ensure that the request is sent by the owner of the data.
For example, consider an update or delete request. You shouldn't be able to make this request for someone else's data. So in addition to the APIKey, I'd like to have something else to ensure that this user making the request is authorized to perform that action.
I could require that an ownerID be passed with such request. But that's quickly forged. So what have I gained.
I am interested to hear what other members of SO have implemented in these situations. Individual APIKeys? Dual-authorization?
If it matters, my API follows the REST architecture and is developed with PHP/Apache.
API keys should be unique per user. This will verify the user and that they should have access to the data.
If you want to be even more secure you can have that api secret be used as a refresh token that can be used to retrieve an access token with an automated expiration.
SSL for all requests is also suggested.
Each API user has a unique API key. This key identifies them as a single user of the system. When dealing with more sensitive data, I've used client side certificates for auth, however Basic Auth + requiring SSL is usually sufficient.
When the request comes in, map the API key to the user and then determine if that user "owns" the resource they are trying to interact with.
The whole "determine the owner" part is a separate issue that can be tricky to do nicely in an API depending on how well the system was built. I can share how we've done that in the past as well, but figured that's a bit off topic.
Suggest you should consider using Oauth. In summary this is how it should work.
Each application making the API calls will need the respective application level APIkey for authorization through the Oauth process. Apikey here would just represent the application (client) identity.
Each end-user associated with the usage must authenticate themselves separately (independent of the apikey) during the Oauth authorization process. The users identity, associated context such as scope of authorization is then encoded into a token called access token.
Once the application obtains this access token, all subsequent API calls to access resources should use the access token, until expiry.
On the API implementation side, the access token validation should reveal the end-user context (including the scope of access that is granted during the Oauth process) and hence the access/authorization to use a specific resource can be managed by the resource server.

Resources