Deploy WebApp to Azure with Zero downtime from VS2015 - azure

I'm trying to publish my web app from VS without no downtime. If you search in Google, you find the official documentation speaking about using slots and do a swap later.
This is a good approach, but I have other problem when I do the swap, logins are lost (look this question: link).
Relevant information in the link:
Session is not linked to Authentication, you're attempting to solve it in the wrong way.
All forms authentication tickets and cookies are encrypted and signed using the data protection layer. The problem you are encountering is due to the encryption keys not being saved, and applications being isolated from each other.
How can I do that? In AWS I had rolling updates...
For more information, I'm using ASP.NET Core with Identity 3.0
Thanks!!

What you're seeing is an azure limitation right now. While Azure Web Sites will share the key ring it sees swap slots as separate applications.
There are a couple of things to try.
First, set a common application name. This will help because every application which shares the keyring is isolated by default; but if they share the application name they can share keys
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection();
services.ConfigureDataProtection(configure =>
{
configure.SetApplicationName("my application");
});
}
If that's not enough for azure (I am honestly unsure if hot swaps end up using Azure Web App's shared key folder) you can combine that with using Azure Data Tables for storing the encryption keys - https://github.com/GrabYourPitchforks/DataProtection.Azure/tree/dev
Between those two it should get the encryption keys used to protect identity cookies shared between your apps.

I found a fork for aspnet core 1.0, for those interested:
https://github.com/prajaybasu/DataProtection.Azure/tree/dev/DataProtection.Azure
just like the other one, it stores encryption keys on an azure storage account.
It completely solved my problem.
Starting from blowdart's solution I solved my issue, so thanks.
Andrea

Are you using in-memory session state?
The problem with 'logins' being 'lost' is an architecture issue, not an issue with updating your web app.
Use something like RedisCache for session state. Not only will it persist when you update your application, but it will handle load-balancing on multiple server instances. As it sits you'll probably have this issue when you scale out to more than one server, in addition to when you update your app.

Related

How we can store API keys encrypted inside .net core console application

I am working on a .NET core console application which integrates with 3rd party APIs. and to do the integration I need to pass the API keys inside the API requests. so my question is where/how I can store the API keys inside my console application? in regular .NET console application I use to store the API keys inside the app.config and encrypt the keys using Aspnet_regiis.. but not sure how i can do so inside .NET core console application?
You can consider...
Get separate keys issued for different environments (so that a compromised key can be expired/cancelled without affecting other environment/s).
Store keys encrypted - for example - in the operating system provided key store [https://learn.microsoft.com/en-us/dotnet/standard/security/cryptography-model]. (This just means that they are not "left lying around" for casual passers by.)
Remove the code for retrieval of keys from the console app, perhaps to a simple service or library to which code the regular developers do not have access. (A level of separation.)
To embed information within the application, consider resource files [https://learn.microsoft.com/en-us/dotnet/framework/resources/creating-resource-files-for-desktop-apps]
Bottom line: This question illustrates the raison d'ĂȘtre for public key (asymmetric) cryptography [https://en.wikipedia.org/wiki/Public-key_cryptography] but any app that handles a piece of information "decrypted in flow" makes that information vulnerable to everyone who has permission to work on (debug) the live app or poke around with diagnostic tools on the system. (If a person needs a key to open a door then you must give them a key with which to open it and can't then prevent dishonest misuse of that privilege.)
A little bit of paranoia is healthy but too much can be an obstacle to getting things done.
Security in Development
For local development, you can use the Secrets Manager Tool (used only in development, never in production). This tool allows you to store your sensitive data locally on your machine, outside the project tree.
This tool is not super secure, and the keys are not encrypted, but it provides an easy way to avoid storing secrets in your project config files and having to remember to add them to the source control ignore list.
Security in Production
A common way is to store secrets in an external vault.
If you are hosting your application on Azure, Azure also provides a more secure option: Azure Key Vault.
Key Vault is a cloud-hosted service for managing secrets, which will be accessible by the applications you authorize through an encrypted channel.
It is advisable not to store encrypted keys inside a .NET console application. It is more ideal to keep secrets separate, store them using the Secret management tool in dev mode, and look into services like Azure KeyVault for production as mentioned earlier.
See the link about app secrets and configuration and why we need a tool to manage it on https://dev.to/dotnet/how-to-store-app-secrets-for-your-asp-net-core-project-2j5b for detailed instructions on how to do this.

How can i implement SSL certificates in a multi-tenant app used for connecting to SharePoint Online?

We're developing a managed app (using ARM templates) that will be deployed to multiple tenants. The solution will, among other things, work with SharePoint sites on the end users' tenant.
We have looked into using a single multi-tenant app registration with the appropriate rights. Because of security restrictions on the SharePoint API when using Azure app-only, a certificate must be added to the app registration and the PFX must be provided in all API calls.
We wish to have as little data at our end as possible, so the we hoped to include the application that connects to SharePoint as part of the deployment. However, this would lead to multiple apps having access to the same PFX, which doesn't seem safe.
I'm hoping there is a better way to go about this. Must the connecting web app instead be hosted on our end? Is there a safe way of storing the PFX in multiple locations, or make it accessible to multiple tenants? It is important to us that we can automate the process as well, preferrably using ARM or an automation job as part of the deployment ... At the very least, I would be thankful for suggestions on making any configurations relatively pain-free for the end user.
PS: We would like to avoid the use of service user accounts.

Using Azure MobileServices library with my own LAN WebApi

I am currently doing some research for the development of a mobile application for our company that should support offline data sync (on an iPad). We have explored many possibilities including PhoneGap/Cordova, Xamarin and simply native iOS development. Xamarin, for many different reasons, seems to be our best choice, so my question will assume we will develop in Xamarin.
I was looking into a library for managing offline data synchronization and the most obvious solution is Microsoft Azure MobileServices. However, my company is Canadian, and apparently it's hard to trust (legally) our data to clouds based in the US. Since we already deployed internally our WebApi on our intranet, I figured there was probably a way to point the MobileServices library to our own WebApi. I have read about the Azure Hybrid Connection possibility, but our data still conveying through Microsoft servers might not be a possibility. So, my question is this:
Is there a way to configure the Microsoft.WindowsAzure.MobileServices Client library to point directly to our intranet, RESTful WebApi backend, without going through any Microsoft Azure servers ?
I understand that, in order to be able to use the Client librairies seamlessly, we probably would have to adapt our WebApi to implement the necessary .net Backend interfaces. I'm mostly wondering if it's even possible as the MSDN documentation on the libraries all seem to point to direct connections to their servers (no possibilities to configure your own connection strings) and all instructions redirect you to their Azure Mobile Services website.
Thank you.
If you look at the API for your mobile client, you'll notice that the Azure Mobile Services Client SDK only cares about two things:
new AzureMobileClient( url, appkey)
...where it's hosted shouldn't be a concern. Everything else is just configuration.
If you want to host the Azure Mobile Services Backend on your own servers, technically you could do this, but there are likely a few caveats. Microsoft has announced that they will be launching a Canadian Azure data center, but we won't see it until 2016.
In the meantime, here's how you can host the services locally. Note that I have not tried to emulate all of the features of Azure Mobile Services (aka Zumo) so your mileage (or kilometerage) will vary.
Hosting Locally:
From a technical feasibility, you absolutely can run the services locally. I know this because you can create the Azure Mobile Services Backend project from within Visual Studio and run it locally for development purposes. This is what our development team does for testing their mobile applications.
Note that you can create the Azure Mobile Service backend directly from within Visual Studio: New Project -> Cloud -> Azure Mobile Service. You can also download the exact same template (pre-configured with your URL and ApplicationKey) directly from the Azure dashboard: Create -> Mobile Service.
Obviously, if you're hosting it on your server it will be up to you to configure and use a proper SSL certificate for your site.
ZUMO Permissions:
By default, the security roles on the server are turned off. So if you're locking down any of your methods using the [AuthorizeLevel] attribute these settings will be ignored at runtime. If you need to enable this feature you can do so by modifying the WebApiConfig.Register() method and marking the site as self-hosted: config.SetSelfHosted(true).
Configuration:
From a configuration perspective, the Azure Mobile Service dashboard provides several tabs for configuring Identity, Push Notifications, Connection Strings and App Settings. Sadly, you won't have a dashboard, but all of these settings have a corresponding value in the local web.config. Any value you provide here is automatically overwritten in Azure, but they're used when running locally.
The minimum settings you'll need to configure are listed here. The ApplicationKey you can distribute with your ZuMo client, but the MasterKey is for the Admin authorization level so you'll want to keep that secret. The MobileServiceName is used by the EntityFramework for your database schema and what appears in the URL of your site.
<add key="MS_MobileServiceName" value="myzumosite" />
<add key="MS_MasterKey" value="masterkey" />
<add key="MS_ApplicationKey" value="appkey" />
Values that start with a MS_ prefix map to corresponding values in the Azure Portal. MS_GoogleClientID and MS_GoogleClientSecret map to the Google Identity values in the dashboard, for example.
Any other value in the AppSettings node is immediately accessible via the ApiServices.Settings property and corresponds to the Settings node in the Azure dashboard.
Database connection strings continue to exist in the connectionStrings node. The same is true for azure notification hub.
Database:
Obviously, the database you configure will be up to you as well. Permissions and User accounts are also obvious. There may be some minor differences between the SQL Azure syntax for Entity Framework database migration scripts that you'll need to worry about. (I've discovered the database migration scripts don't work from the Package Manager, but they do work when the database scripts are run when your website starts)
Caveats:
You will not have a nice dashboard for monitoring performance of your site, reviewing logs or changing runtime settings
You will not be able to scale out your site immediately; Scaling and deployment will be your problem
Deployment configuration is your responsibility (Project -> Publish won't be available unless you configure it)
Not sure if you'll be able to use Azure Active Directory as an authentication scheme, though from the sounds of it that won't be a concern. You can write your own authentication providers: Microsoft's Zumo library only supports a handful, but the underlying Owin.Security package that Microsoft uses supports several dozen systems!
Your site will need to be publically visible to your mobile clients
Push Notifications should work, but you will be using Azure's notification hub for this.
I have no idea where ApiServices.Log will go
The easiest path to take would be to:
Create the Mobile Service in Azure to get the notification hub and settings preconfigured
Download the starter site from the dashboard
Configure the web.config as mentioned here.
It's not possible to simply configure WAMS Client library to work with your own WebApi Backend.
But WAMS library is available at github, so I'm sure you can reuse a lot of code from the WAMS project, especially if you want to use a PCL project.
To route your data securly through Azure, you could think about setting up express route. Additionally, for last weeks update, it's possible to apply a custom domain to the WAMS Backend, including your own certificate to secure your connection.

Unique account manager

I've got three different apps, all in GWT, none using Spring. Today, all of them got their own security layer provided by Tomcat. I want to setup a security layer shared by all of them. So that I don't have to deal with changes in the security layer for every app (following the DRY principle). I believe it's something similar to what Google does. Every time I try to login to any Google app, I'm taken to account.google.com.
How can I do that? Maybe setting this webapp Accounts to deal with every aspect of the accounts (log in and out, edit account, etc), and connect the session (or authentication) to my webapps?
You could deploy a Central Authentication Service and use it as an authentication provider for your applications.
Using a library (for example gwt-cas) to call your CAS will reduce your code duplication to a few lines of configuration per project.
You'll want to look into container-managed security. Here's the salient documentation.

Does connect.session work with node-azure

I'm starting to develop an application using node.js on azure. I'm using everyauth to provide authentication because I want to support lots of different authentication methods. I plan to deploy to Azure. The potential problem I have is that everyauth requires the connect.session helper. Will this work with azure when running multiple instances? Or do I need an alternative session provider?
I have never used Node.js on Azure, but:
everyauth
Looking at the documentation for everyauth there is a method for authenticating against a Windows Azure ACS. See the section entitled Setting up Windows Azure Access Control Service (ACS) Auth in the readme for more information. There are no notes there about it not working on Azure itself so I would infer from that that you can use it on Azure.
connect-azure
There is also a project called connect-azure, which appears to be using connect.session so again I would extrapolate from this that it will work on Azure.
Contact Azure support
If you are already a customer you can contact support for help.
Try it and see
So if you have the Azure environment setup I would definitely say it is worth trying it out.
This was asked a while ago, but I thought I would attempt an answer anyway. It seems that connect-session relies on cookies to maintain the session. Azure has a different load-balancing strategy depending on what you use:
WebRole/WorkerRole - the LB doesn't have any affinity so requests from your clients might end up at different backend instances. This will throw off whatever session management connect is doing. This is a side effect of a distributed cloud architecture: you don't want any backend node to be the source of truth since it can go down. So what you would have to do is figure out how to externalize connect's cookie store and have all backends share it. This way no matter what backend receives the request, it will be aware of the session.
Websites - in this case the LB will actually try to pin a client connection to a given backend instance, so cookie-based sessions may work without any changes. You are sacrificing failover, as described above.

Resources