how to share Azure mobile service tokens across different web app instances - azure

I am planning to have multiple azure mobile service instances, so the first requirement I have is to share the access token of authenticated user across different app instances. I found this article https://cgillum.tech/2016/03/07/app-service-token-store/ that states that right now we can not share the tokens as it is stored locally on machine, and placing it to blob storage is not recommended for production apps. What is the possible solution I have at this time?

I have read the blog you mentioned about App Service Token Store. As mentioned about where the tokens live:
Internally, all these tokens are stored in your app’s local file storage under D:/home/data/.auth/tokens. The tokens themselves are all encrypted in user-specific .json files using app-specific encryption keys and cryptographically signed as per best practice.
I found this article https://cgillum.tech/2016/03/07/app-service-token-store/ that states that right now we can not share the tokens as it is stored locally on machine.
As Azure-runtime-environment states about the Persisted files that an Azure Web App can deal with:
They are rooted in d:\home, which can also be found using the %HOME% environment variable.
These files are persistent, meaning that you can rely on them staying there until you do something to change them. Also, they are shared between all instances of your site (when you scale it up to multiple instances). Internally, the way this works is that they are stored in Azure Storage instead of living on the local file system.
Moreover, Azure app service would enable ARR Affinity to keep a client subsequent requests talking to the same instance. You could disable the session affinity cookie, then requests would be distributed across all the instances. For more details, you could refer to this blog.
Additionally, I have tried to disable ARR Affinity and scale my mobile service to multiple instances, then I could always browser https://[my-website].azurewebsites.net/.auth/me to retrieve information about the current logged-in user.
Per my understanding, you could accomplish the authentication/authorization by yourself to use auth middle-ware into your app. But, this requires more works to be done. Since the platform takes care of it for you, I assume that you could leverage Easy Auth and Token Store and scale your mobile service to multiple instances without worrying about anything.

Related

.NET Core Dependency Injection and services that utilize frequently rotated authorization keys

Issue Summary
I have multiple ASP.NET Core applications that connect to Azure resources such as CosmosDB, Azure Storage Queues, Azure Event Hubs, etc. All of these resources can utilize Shared Access Signature (SAS) tokens for authentication. These tokens expire which presents a problem when my application starts up and initializes the service once upon startup via services.AddSingleton<T>() (or a similar option).
For example, what I typically do is read the SAS token from a file upon startup (likely mounted to my pod as a volume in Kubernetes but I am not sure that's terribly relevant). That SAS token is then provided to an Azure Storage Queue Client constructor, like this:
string sharedAccessSignature = File.ReadAllText(pathToSasToken);
services.AddSingleton<Azure.Storage.Queues.QueueClient>((sp) =>
{
return new Azure.Storage.Queues.QueueClient(queueUri,
new AzureSasCredential(sharedAccessSignature),
new Azure.Storage.Queues.QueueClientOptions()
{
MessageEncoding = Azure.Storage.Queues.QueueMessageEncoding.Base64
});
});
Unfortunately, I think this means once my SAS token expires, my QueueClient will no longer be able to connect to my Azure Storage Queue without restarting my whole application. Somehow, I need to re-read an updated SAS token from my file while I remain running. (I have another process running in my cluster that provides SAS tokens to my pods).
Possible Solutions
I figure the IOptionsMonitor approach could be useful but unfortunately, the SDKs for these clients don't accept an IOptionsMonitor<T> in their constructors so they don't seem to be capable of re-reading new tokens at runtime -- at least not using IOptionsMonitor.
Another approach could be to use Transient or Scoped service lifetimes but that requires I use the same service lifetimes in my whole dependency chain... So if I have a singleton like a HostedService running, I cannot resolve a Transient or Scoped service from that without unpredictable results (AFAIK). (Update 12/31/2021 - This is actually not true. Microsoft provides guidance on how to consume a scoped service in a HostedService which is actually a good example that demonstrates how one can use Scoped services and manage the lifetimes on your own).
I could also just manually re-create my clients as my code is running but that seems to defeat the purpose of using the .NET service provider and DI pattern.
Am I missing an obvious solution to this that I'm just not seeing in Microsoft's documentation?
I think you're missing Managed Identities. Rather than trust on SAS tokens, you assign a Managed Identity to your ASP.NET app, and grant access to this identity to connect to the required services.
Benefits:
no need to redeploy / acquire new SAS token when it changes / expires
external users won't be able to impersonate this identity (if someone get access to the SAS token, they will be able to use it outside the scope of your app)
More info:
https://learn.microsoft.com/en-us/azure/storage/blobs/authorize-managed-identity
https://learn.microsoft.com/en-us/azure/cosmos-db/managed-identity-based-authentication
https://learn.microsoft.com/en-us/azure/stream-analytics/event-hubs-managed-identity
https://cmatskas.com/setting-up-managed-identities-for-asp-net-core-web-app-running-on-azure-app-service/

Azure web app session and ARR

I have a MVC application deployed to Azure Web app.The web app required to scale out in multiple instances.
I want to use Session object (ASP.NET) to store some user data etc.(lightweight), so that can be retrieved quickly.I believe, session will be In-Proc with ARR ON setting.
I've the following questions
Is it ok to use session object in Azure web apps ,will it give
guarantee to use same In-Proc session if ARR is on.
If ARR turned off ,Should I use session object?
Because using Session itself makes application slow,what are the
other alternatives to store small data within Azure webapp/MVC(once authenticated user profile
related data) for quick access in application?
Using IN-PROC sessions in the cloud is a strict no. The reason to host to cloud is to have high availability which is done by having a distributed environment.
To answer your question, the ARR-Affinity cookie will affinitize the client requests to a specific instance. However, if the Process restarts or App-Domain recycles, then all the sessions will be lost. This is one of the primary reasons why Out-Proc session state management is suggested.
I would recommend against using In-Proc session state in any cloud scenario. I understand speed is a concern for you. For this consider using Redis Cache. Refer the documentation here: https://learn.microsoft.com/en-us/azure/redis-cache/cache-aspnet-session-state-provider
HTH

Azure:limit the access of ARM PaaS services to certain storage accounts

I have a security question related to Azure that I could really do with some guidance on the art of what is possible.
I would like to know if it is possible to restrict what services can be called (i.e what storage account endpoints can be used to write data to) from PaaS services such as service fabric or web apps (ASE). i.e. if I have a web app that writes to storage and someone maliciously altered the code to write to a third party storage account on Azure; is this something I could mitigate in advance by saying this application (i.e. this web app or this SF cluster) can only talk to a particular set of storage accounts or a particular database. So that even if the code was changed to talk to another storage account, it wouldnt be able to. I.e can I explicitly define as part of an environment what storage items an application can talk to; Is this something that is possible?
Azure Storage Accounts have Access Keys and Shared Access Keys that are used to authenticate REST calls to read / write data to them. Your app will be able to perform read / write operations against the Azure Storage Account that it has an access key and connection string for that it uses to connect to it with.
It's not possible to set any kind of firewall rule on an Azure App Service app to prevent it from communicating with certain internet or Azure endpoints. You can set NSG firewall rules with App Service Environment, but you still can only either open or close access; not restrict on certain DNS names or IP Addresses.
Perhaps you should look for a mitigation to this threat in the way applications are deployed, connection strings are managed and code is deployed:
Use Azure Role Based Access control to limit access to the resource in Azure, so unauthorized persons cannot modify deployments
Use a secure way of managing your source code. Remember it is not on the PaaS service, because that only holds the binaries.
Use SAS tokens for application access to storage accounts, not the full access keys. For example, a SAS key could be given write access, not read or list access to a storage account.
If, as a developer, you don't trust the person managing the application deployment, you could even consider signing your application parameters/connection strings. That only protects against tampering though, not against extraction of the connection string.

Azure blob storage and security best practices

When exploring Azure storage I've noticed that access to a storage container is done through a shared key. There is concern where I work that if a developer is using this key for an application they're building and then leave the company that they could still login to the storage account and delete anything they want. The workaround for this would be to re-generate the secondary key for the account but then we'd have to change all of the keys in every application that uses those keys.
Is it best practice to have an entire storage account per application per environment (dev, test, staging, production)?
Is it possible to secure the storage account behind a virtual network?
Should we use signatures on our containers on a per application basis?
Anybody have experiences similar and have found a good pattern for dealing with this?
I have a bit different scenario – external applications, but the problem is the same - data access security
I use Shared Access Signatures(SAS) to grant an access to a container.
In your scenario you can create Shared Access Policy per application on a container and generate SAS using this Stored Access Policy with long expiration time, you can revoke it at any point by removing Shared Access Policy from container. So in you scenario you can revoke current SAS and generate new one when your developer leaves. You can't generate single SAS for multiple containers so if you application uses multiple containers you would have to generate multiple SAS.
Usage, from the developers perspective, stays the same:
You can use SAS token to create CloudStorageAccount or CloudBlobClient so it’s almost like a regular access key.
Longer term, I would probably think about creating one internal service(internal API) responsible for generating SAS and renewing them. This way you can have completely automated system and with access keys only disclosed to this main service. You can then restrict access to this service with virtual network, certificates, authentication etc. And if something goes wrong (developer who wrote that service leaves :-) ) you can regenerate access keys and change them, but this time only in one place.
Few things:
Storage account per application (and/or environment) is a good strategy, but you have to be aware of the limit – max 100 storage accounts per subscription.
There is no option to limit access to a storage account with virtual network
You can have maximum 5 Shared Access Policies on a single container
I won't get into subjective / opinion answers, but from an objective perspective: If a developer has a storage account key, then they have full access to the storage account. And if they left the company and kept a copy of the key? The only way to block them out is to regenerate the key.
You might assume that separating apps with different storage accounts helps. However, just keep this in mind:if a developer had access to a subscription, they had access to keys for every single storage account in that subscription.
When thinking of key regeneration, think about the total surface area of apps having knowledge of the key itself. If storage manipulation is solely a server-side operation, the impact of changing a key is minimal (a small app change in each deployment, along with updating any storage browsing tools you use). If you embedded the key in a desktop/mobile application for direct storage access, you have a bigger problem with having to push out updated clients, but you already have a security problem anyway.

Does Windows Azure have the equivalent of AWS Identity Access Management?

So I have a mobile app that uses AWS's IAM infrastructure that effectively allows me to provide temporary access tokens to anonymous mobile devices, so that they can run queries against AWS services directly from the mobile device.
Does anyone know if Windows Azure has a drop in replacement for this sort of thing too? I've read about Windows Azure Access Control but all examples seem to focus on allowing authentication via the likes of Facebook, Twitter or Windows Live etc. In my case, I don't want the mobile user to have to "log-in" anywhere, I just want them to be able to access Azure services such as table storage, without having to go via my server.
Thanks!
You do have the ability to create Signed Access Signatures for all three Windows Azure Storage services (BLOBs, Queues and Tables) as well as for Windows Azure Service Bus Brokered Messages (Queues, Topics & Subscriptions). These SAS urls are temporary and you can create them ad-hoc with expiration times. After that time expires the device would have to request a new one, likely from your server. This reduce the load as they aren't coming back all the time, but you do still have to run something that will gen these SAS uris for the devices. You can generate SAS manually against the REST API direct, or you can use one of the SDKs to generate them for you (which also hit the REST API).
Note that when you create a SAS you have the option of doing so as a Policy, or adhoc. A policy allows you to revoke a SAS at a later time, but you can only have so many of these defined at a time (likely too big of a restriction for a mobile scenario if you are doing by device). The adhoc approach allows you pretty much as many as you need (I think), but you don't have the ability to revoke it, it just has to expire.
Another option is to look at Windows Azure Mobile Services. This service runs on servers managed by Microsoft and you can use it to get at just about anything you want. You'd want to look at the "Custom API" feature. Also, make sure you understand the pricing model of mobile services (or really, that stands for any option you decide to go with).
It's called managed identities in Azure

Resources