.net core distributed apps key/secret storage - asp.net-core

We are making an app that will be distributed to clients to host themselves, or with a provider, and are wondering what the proper method of key storage is for a .net core web app.
We would like the database connection string and a few needed api keys to be included with the server, but not accessible to the clients. Most search results we could find relate to user secrets for development, but they don't explain what to do for releases/production.
I did find some information on data protection, but I also read that it is meant for keys that are changing, not keys that are static. Any help is much appreciated!

Related

Can I create a 'proxy' for an ArcGIS service?

I am in a situation where we have a Feature Service that is not publicly available. Of course, this means that it is not possible to access it directly from JavaScript (and it is not desirable as well as it has some sensitive information).
Therefore, what I was thinking is that instead of our Web App connecting directly to the ArcGIS services, it would connect to our 'proxy / middleware / man in the middle' system, and this would in turn authenticate and query ArcGIS. This would also allow us to restrict any access to sensitive data while enriching the data through our data that lives somewhere else.
I have a gut feeling that this is completely wrong..and the way to do it is to create some publicly available space and do the enriching on ArcGIS itself. From a business case, this is the least desirable route.
Thanks!

Using .Net Core Identity and OIDC with Multiple .Net Core Web API

I need to build an application where the front-end (ReactJs) is totally decoupled from the back-end, which is built using Asp.Net Core v5 (or higher) Web API.
Users will log in to the application using both OIDC with Azure Active Directory and local database login.
For performance reasons, I'd like to split some APIs into different projects and eventually install them on different servers.
I'm wondering if the [authorize] attribute I will put on the endpoints will work as usual even if they are running in different environments.
Please note that they could be different servers or different AWS Lambda functions, but in both cases, they can be considered different executables.
Is it something possible or I'm going in the wrong direction?
Please note that they could be different servers or different AWS
Lambda functions, but in both cases, they can be considered different
executables.
Is it something possible or I'm going in the wrong direction?
Thank you # Camilo Terevinto, Posting your suggestion as an answer to help other community members .
"It's completely possible (and common), as long as all APIs (and possibly Lambdas, depending on how they're used) authenticate against the same Azure Active Directory instance.
And we can set up ASP. NET Core Identity with both local login and AAD without any issues . Just ensure that our tokens always have the necessary scopes (to call other APIs in our system)"
For more information please refer the below links:
SO THREAD : How to use both Azure AD authentication and Identity on ASP.NET Core
Blog: Token Based Authentication using ASP. NET Web API 2, Owin, and Identity

How to provide credentials to a service which is need to use an thirdparty service

I need some advice about architectural design or best practice approaches.
I have a service that needs some credentials for some third party services.
My Service used by a webapp which currently keeps this credentials in a DB in encrypted mode.
WebApp and MyService are going to communicate over a MessageQueue (RabbitMQ).
How can I provide my Service these credentials from web app. Or should I completely change the design and how?
Thanks in Advance
KR
Timur
This is a complicated area, and different people have different ideas about how to do this; the problem with your design is that an attacker who can sniff the traffic between your web app and your services can get access to your keys.
You also have tight coupling between your apps and your services, as well as all the entertainment of managing credentials between dev, qa and prod environments.
Many hosting strategies include a "key management server" for this purpose - AWS has https://aws.amazon.com/kms/, for instance. I'd suggest reading up on their use cases.
Another popular solution is to store the keys in environment variables, and manage them as part of your build/deploy pipelines.
Finally some frameworks (e.g. Ruby on Rails) store these details in a credentials file, and have workflows for managing them outside the source code control processes.

Sharing user login between Blazor WebServer and ASP.NET Core API

I am building a service-oriented system for personal use (plus few friends may have limited access as well) - the aim is to have a dashboard for controlling my apps running on various machines such as Raspberry Pis (and potentially to be expanded to a VPS or few in future).
The architecture itself is pretty simple. For authentication I want to use AWS Cognito. Services would communicate with WebAPI (and potentially with eachother) using gRPC within a VPN, and dashboard would be served by Blazor server-side (may move to Blazor WASM Hosted model if I find a need for it). Each of the processes may or may not be on the same machine as any other (depending on the purpose). Blazor server may or may not run within VPN (I might want to move it to a separate web hosting later).
I created a simple diagram to visualize it:
The problem comes with authentication. I want to have Blazor server-side and API as a separate processes (for now they're going to run on the same machine, but I may want to move it elsewhere eventually). Ideally authentication should be handled by API, so authentication is client-agnostic, and the API can use it to verify if the logged in user can perform an action - which by itself is simple.
However, I want Blazor server to use and validate that token as well in order to determine what to display to the user. I want to do with the least amount of calls possible - ideally avoiding querying API for every 'should I display it or not?' choice.
I could easily do it by sacrificing possibility to move API elsewhere, and just merge Blazor Server and API Gateway into one project. For my current purpose it would be enough, but it's not an ideal solution, so first I want to look into how could I achieve my original vision.
How could I achieve this (with minimal amount of Blazor server to API queries)?
I was googling for solution a lot, but so far only found either examples of using Blazor server and API as one project, or using client-side calls to API directly.
Thank you good folks in advance.

ASP.NET Core Data Protection on Web Farm

I have a ASP.NET Core application that uses cookie authentication and runs on web farm. The data protection keys are stored in DB. My application implements the IXmlRepository and the ASP.NET Core will call the IXmlRepository.GetAllElements to get the key ring. So, application in all nodes are using the same key ring and cookie encrypted in Node1 can be decrypted in Node2. It works fine.
However, data protection key will expire and ASP.NET Core will generate a new key. ASP.NET Core also cache the keys and will refresh each 18-24 hours. So, when the key expires, Node1 may generate a new key, but all other nodes may not refresh right away and get the new key. Cookie encrypted by Node1 cannot be decrypted in all other nodes.
How can this situation by handled by ASP.NET Core?
I read this https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/web-farm?view=aspnetcore-2.2, it states
The default configuration isn't generally appropriate for hosting apps in a web farm. An alternative to implementing a shared key ring is to always route user requests to the same node.
Is it the only option to route all requests to the same node after user login using that node?
In principle, this is no different than any other shared configuration scenario. You need to do two things:
Persist the key ring to a common filesystem or network location path all the processes/apps can access:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(#"\\server\share\directory\"));
Ensure that all the process/apps are using the same application name:
services.AddDataProtection()
.SetApplicationName("shared app name");
The second item is less important for a web farm scenario, since it's all the same app and will have the same app name by default. However, it's always better to be explicit, and then if you do need to share with an entirely different app, you're already set up and ready to go.
In short, you need to add the following code:
services.AddDataProtection()
.SetApplicationName("shared app name")
.PersistKeysToFileSystem(new DirectoryInfo(#"\\server\share\directory\"));
To #LGSon's point in the comments below your question, you'll also run into an issue with caching/sessions eventually, as well. Regardless of being the same "app", you should think of the each instance in the web farm as a separate app. Each is a separate process, which means they have their own separate memory allocation. If you use memory caching (which is also the default storage for sessions), then that will be available only to the individual process that created it. Each process will therefore end up with separate cache and separate sessions. To share this information, you need to employ a distributed cache like Redis or SQL Server. See: https://learn.microsoft.com/en-us/aspnet/core/performance/caching/distributed?view=aspnetcore-2.2#establish-distributed-caching-services.
Note: Even though there's a "distributed" memory cache, it's not actually distributed. This is just an implementation of the IDistributedCache that stores in memory. Since it stores in-memory, it's still process bound.
There's an interesting GitHub issue discussing the key ring storage and key rotation here
https://github.com/dotnet/aspnetcore/issues/26786
Also, if you want to know more about how you can store the key ring in Azure Key Vault, then I recently blogged about that here:
Storing the ASP.NET Core Data Protection Key Ring in Azure Key Vault