GraphQL - Triggering a selective subscription from a BackgroundService - c#

I am facing an architectural issue with the following setup:
A frontend (React), an ASP.NET Core Backend that consumes messages from a Kafka server. The frontend receives a token from an Auth0 instance that also returns a tenant id inside that token. THe ASP.NET Core middleware, when a resource is requested via the GraphQL (using HotChocolate) query, retrieves that token and gets the tenant id. With that, if data is queried, only data for that specific tenant is returned without the client knowing anything about this.
Now this works fine - the problem arises when a message from Kafka arrives. Currently it is a IHostedService, then when an event comes in, can use a ITopicEventSender to inform clients about that message. The message contains also the tenantid.
Only clients that share the same tenant id as the message should be informed. My idea was to let the client pass in the tenant-id as a parameter for the subscription, but how to make this tamper-proof so that a client doesn't get messages from a different tenant.
Is there a better way of achieving that without the chance of the client to tamper with the data?
Here the flow as a small diagram:

Related

Securing External API EndPoint for ASP.NET Web API Service (ASP.NET 4.6)

I'm building an external API endpoint that will send email notifications to subscribers. When a subscriberID (50 characters) and a message string is passed to the endpoint, the service will send out a message via email to the subscribers email address. Due to the nature of the service it cannot be locked down by IP address or a certificate file or use OAuth2. A third party will be hitting this endpoint with messages to send out to subscribers.
There are currently 100,000 plus subscribers, what are the odds if a malicious user were to find this endpoint that they could randomly try subscriberIds and find valid ones and start sending them emails given the fact that an ID is 50+ characters long and there are about 100000 valid subscriberIds.
What are my best options for securing this API endpoint? Here are my thoughts so far, either add a api key that only the third party knows and will send on every request and/or generate a token for every subscriber and save it to a database and then on the endpoint require them
A good solution for securing Web API's is using JWT
If you are building your Web API using ASP.NET Core, it's much easier to use it, as it is a built-in feature.
Also, do you have some limitations regarding the number of emails a subscriber can send? It may be a good idea to have a threshold for each user (every minute,hourly,daily,etc), so you can avoid been spammed by a malicious user that has access to your Web API.

Azure Functions proxy authentication

I need to create a proxy working as Azure Functions between two APIs. Let's draw a little diagram:
[API A/client] <----> [proxy] <----> [API B/backend]
The backend API has a custom authentication scheme - in order to be authorized to use all endpoints we need to get Session Token first. Then we put it as an Authenticate header - this way calls to other backend's endpoints will not result in some kind of 401 or similar.
Client's view n authentication is not defined yet (meaning that we haven't reached it's techinical team yet) so it's hard to assume anything but let's say it will handle whatever we tell it to do.
How to implement such auth scheme for our proxy? I was thinking about following approach:
client calls proxy's method GetSessionToken anonymously
proxy calls backend's method GetSessionToken anonymously, backend responds with Session Token in in response body
proxy creates a jwt token that keeps the Session Token, proxy attaches this token as a Authentication/Bearer header in response to client
I just started using Azure Functions a few days ago and while I know how to implement this as an usual .net core app, I have no idea how to do it in Azure Functions which are not as sophisticated.
Daniel
Proxies currently don't support extracting some value from response body and adding it to a response header. You might need to do this in a function code or use Azure API Management.

WCF: Is Authentication / Authorization inside a message inspector a good design?

This question is not about HOW something can be done. Everything is working fine. I like to know, if it is "ok" to do the authentication / authorization process inside a WCF message inspector.
Currently I am working on a client/server application with a WPF client and a self-hosted WCF server. The used protocol is Net.Tcp and all SOAP messages are AES256 message-encrypted and signed. Also all send SOAP message-headers are always message-encrypted and signed.
The complete auth process looks like this:
Both server and client are always sending certificates to authenticate each other
Client receives a list of all endpoints it can connect to
Client sends User/Pass to authenticate and gets a session-id from the login-service
The session-id, the user-id and all user-rights associated with the user-id are stored into RAM in a singleton service, which is available system-wide inside the server application.
On every further request after the first login, the client only sends the session-id and a certificate inside a custom message-header, no more user/pass combination.
The situation:
Before a request from the client reaches any webservice operation, a message inspector reads the session-id and the requested webservice operation. It then uses the available singleton-service to determine if the session-id is still valid and if the associated user-id has the right to do this webservice operation. If not a fault-exception is thrown.
The question:
Is there anything wrong, to do the authentication / authorization process inside a WCF inspector?
If its working then dont break it :) But to answer you, I have put some insights for your to consider:
1- For service operations that dont require authentication, you would have to change the inspector code to whitelist them. This contradicts with the open close principle where your class must be open for extensions and closed for modification.
2- If later on, you decide to modify your authentication mechanism and use a third party component, you would have to modify your interceptor code drastically.
I usually use the WCF inspector to pass the token and other related info into my services classes where i normally implement the cross cutting concerns (Validation, Authentication, Authorization, Logging and exception handling). When you inject your authorization engine into your services, it becomes easier for you to first swap the mechanism when need be, second unit test your service method in isolation of whatever authentication mechanism you are using.

In an Azure Mobile App Services client, how do I set the userId so loginAsync works?

I'm implementing custom authentication in a Xamarin.Forms app that uses a .NET backend in Azure, some of the controllers are marked with [Authorize]. I've followed instructions from a multitude of blogs and articles, but it's still unclear how to make TableController calls that are unauthorized trigger a login screen, or how to access the same authentication subsystem loginAsync does to set the userId or token information so that multiple instances of MobileServiceClient retains the latest userId and MobileServiceAuthenticationToken values. How do I correctly trigger a login page and update the userId / token in the same authentication subsystem MobileServiceClient accesses with the other OOTB providers?
When your mobile app tries to access a backend that is marked with [Authorize], but an authorization header is not provided (technically, an X-ZUMO-AUTH header with a valid JWT), the service returns 401 Unauthenticated. There are a number of ways to trap this, but your operation will fail (and in a Xamarin.Forms application, that will cause a MobileServiceInvalidOperationException). You need to handle this case, call loginAsync() and then re-try the operation.
You should not have multiple MobileServiceClients - you should have one at a global scope (use DI to inject it or just make it a static in the App context). The MobileServiceUser will be used by all tables that are generated.

Handling security in an ASP MVC application that uses JS to a REST API

I have an ASP MVC4 web site. Originally, most of the content was served via controllers as one would expect. I have moved the data storage from SQL Server to MongoDB. I have also added a lot of ajax to update data client side, without a full refresh. This is working fine, but my controllers now have lots of methods that take json and return json. I was able to build a Node.js server that hits the database and exposes exactly the same functionality, without lots of going to and from C#.
My javascript client-side is now calling a Node.js REST API, this works great. My 'secure' code (like adding a new user) hits the same REST API from the server side.
My question is this: How can I handle security properly with this? I have three scenarios:
GET api/messages: No need for security, I want to expose my site's messages to anyone who is interested via a Json REST API.
GET api/my/messages: I need to allow access to this only if the user is logged in (it gets the user's messages).
POST api/users: This is a function that should only be called from the server, and nothing else should be able to use it.
As the user is already logging in to my ASP website, how can I use their logged in credentials to authenticate them with my REST service? While the user is logged in, the pages client side will hit it regularly for updates.
Is there any sensible/standard way to do this? The core idea is that the client side code uses a REST API that is at least partially open to the public, and that in fact that API offers all of my business logic - only parts of it (like creating a user) are locked down to super-admins only.
Thanks in advance!
Create two authentication middleware handlers. One you add to all your "my" routes and another which you add to your POST routes.
The "my" authenticator takes the asp.net auth cookie that is present in the request and makes a http call to your asp.net mvc site with it.
You'll need an action which either returns a 401 if the cookie is invalid otherwise it returns some info about that user's permissions perhaps.
If the request into node doesn't have a cookie, return a 401 again.
In addition, to prevent excessive calls to your mvc site to check the cookie, you could use the cookiesession middleware to set a cookie on the client with a flag of authenticated. That will result in 2 cookies for your client, but that shouldn't be an issue. Just make the node one expire before the aspx one.
The POST authenticator middleware can use any shared secret you like between your node and mvc server. e.g. a special header in the request.
If the user is required to login you can use [Authorize] on your controller actions. Autorization will be handled like any other webrequest.
Furthermore you might consider to add a key to your api requests which you can provide in the initial page load. A autorized user will have a GUID which he will sent with the api call. You can check if this key was issued by your app to a valid user.
As you said all the secure calls already go through your MVC server code which in turn calls the Node.js code, am I right? Basically you need a way to block calls to this Node.js from other clients that are not your MVC code.
Thinking out loud, these are the ideas that pop into my mind:
Use SSL only between MVC and Node. You can set up client and server certificates so that the Node code will only respond after authentication (I don't know how Node handles SSL so you will need some documentation here
If you want, the Node server could also check the call origin and so you can filter based on IP and only allow IPs where your MVC code is sitting
Use an encrypted authentication token on the secure methods on the Node code. Again I'm not really a Node expert but I can imagine it has ways of decrypting a token, or you can simply base it on a random number with a common seed... If noone has access to your server code ideally noone should be able to guess this token. Again, SSL will help against traffic sniffing
I am quite sure that people will come up with other ideas. For me, the most basic thing is anyway ensure that the secure methods are only accessible through an SSL connection and on this connection you can exchange all the info (token, passwords, etc.) you desire.

Categories

Resources