📜 ⬆️ ⬇️

Publish to Azure Blob Storage with Shared Access Signature

Hey. This article will be very similar to the previous one . Here I will also tell you how to use Windows Azure Mobile Services to publish high-volume data to Blob Storage. However, this time we will get rid of the WCF service and at the same time add an additional layer of protection against unauthorized access using Shared Access Signature . The purpose of this article is to show the additional features of Windows Azure for working with data, as well as the ability to quickly create a Mobile Services backend.

Before proceeding to further reading, I advise you to read the previous article, because there some points are disclosed in more detail than here.

Shared Access Signature


For a start it is worth telling, and what is this very Shared Access Signature, or simply SAS. Behind these three letters lies nothing more than a simple URL that allows you to differentiate the right of access to a Windows Azure Blob resource, Table or Queue. If you recall the previous article and how data was exchanged between the Windows 8 application and the WCF service, you can immediately understand that this solution clearly suffered from the lack of any protection. First, the data channel was opened (HTTP), which allowed a potential attacker to intercept user information. Secondly, even if the channel is encrypted (HTTPS), we did not have any verification of the authenticity of the request. I want to say that if we had several users in the system, then there was no way to determine whether a particular user has write permissions to the repository, and in general - whether the application sent a request or is it just a hacker trying to send its malicious data. Well, I don’t even consider the option of storing data for connecting to Blob Storage directly in a Windows 8 application - it’s not too security.

Using Shared Access Signature in conjunction with Mobile Services will allow us to avoid such problems. The fact is that SAS will be formed on the server side, directly in Mobile Services, where we are protected from prying eyes, and we also have all the necessary information about the user and can restrict access to anonymous people. The very same signature will be issued for a very limited period of time, about 5 minutes, which will also minimize the possibility of its embezzlement and mercenary use.
')
Perhaps the words are quite difficult to explain, so I propose to move on to practice. For this, I will take the idea from the previous post and a slightly modified application code.

Training


So, first we need to create the necessary services in Windows Azure. Go to the new management portal and create Blob-storage. Through the standard menu of adding a service, select the item Data Services -> Storage -> Quick Create, where we need to specify the name of the future service, the region of the subscription, within which it should work:

Creating Windows Azure Blob Storage

We also need a mobile service, which can be created in the same portal menu in the Compute section -> Mobile Service:

Creating a Windows Azure Mobile Service

Both of these steps you can not do if you already have a blob-storage or mobile service created.

Create Shared Access Signature


Unlike what we started last time, now our first place to write code will be Windows Azure Mobile Services. Yes, I have not described myself anywhere here - we will write code directly in the cloud service. This is possible thanks to the built-in functions of scripts that can be executed when performing one of the CRUD operations on the table.

This time we will save photos with a brief description in our application. To begin with, we will create a new table in Mobile Services, in which the records will be located. Let's call it Picture:

Creating Data Table

When creating a table, in the fields with the name Permission specify “Anybody with the application key”. This means that any user (even anonymous) who has access keys to the Mobile Service can perform this operation. If you select the value “Only authenticated users”, then the user will be checked before accessing the operation, and if it is not specified, the operation will be prohibited from being executed. In this article I will not consider authentication using Mobile Services, so we will leave the default values ​​in these fields.

Now that the table has been created, you can open the scripts. To do this, go to the Data section in the control panel of your mobile service, select the table you just created. At the top, she will have access to the Script section, which we need:

Script Data Table

If you expand the Operation menu, it will have four options: Insert, Update, Delete and Read. Each of these options corresponds to a separate script that is executed at the time of the occurrence of an event. If we draw an analogy, then these scripts can be compared with database triggers. In this case, the main body of the “trigger” itself is the function of the same name, but you can write additional functions below. The language of these scripts is JavaScript, with all the ensuing positive consequences, in the form of asynchrony, closures, etc.

So, when it became a little clearer with the principle of the scripts, it’s time to write a little server code that will create Shared Access Signature for us. For this we need a script for the insert event - Insert. Scripts in Mobile Services allow you to use some APIs to work with other Windows Azure services. Such APIs are connected as external library classes and are used in the code easily and simply. Let's look at this with an example (I apologize for inserting the code as a picture, but more clearly):

Shared Access Signature 1 Script

Lines 1 and 2 just declare the plug-ins and give them names. The azure module is responsible for working with Windows Azure services, and the querystring module is responsible for generating a URL with parameters (see below). However, before we proceed to the consideration of the code (which, by the way, should be quite understandable), I want to draw your attention to how convenient the built-in editor is. Firstly, there is syntax highlighting and automatic alignment, which, however, will surprise no one. Secondly, it has built-in automatic code validation. The createAccessPolicy and createResourceURLWithSAS functions are not yet declared in the code, and the editor highlights them with an underline and a red bar in the margins. Well and in addition, thirdly, IntelliSense is built in the editor. He, of course, not as cool as in Visual Studio, but also slightly simplifies life.

Now look at the code itself. As I said, there is nothing complicated and incomprehensible. If in a nutshell, we, along with the recording of information about the new image, also need to record the URL, with which we can perform operations with BLOB storage (this URL contains SAS). First you need to access the repository using its name and key (line 14), which can be obtained in the Windows Azure management portal in the storage management section. Then we create a container (line 15), if it is not already there, and set access rights: allow reading to everyone. Then, using an anonymous function and closures, we determine the code that will be executed after the container is created. So we achieve asynchronous operation of the application, which is better for server performance. Using the createAccessPolicy function (line 20), which is not yet described (line 20), we create an access policy (what we can and when) and create a URL using createResourceURLWithSAS (line 23).

Let's look at the rest of the code:

Shared Access Signature 2 Creation Script

This code snippet contains the remaining functions that were missing in the previous block. The most interesting are createAccessPolicy and getSAS . The first simply returns a special object that describes the access policy. We create it with write-only rights, and also specify the expiration time of the rights - 5 minutes from the moment of creation. Explicitly setting the SAS lifetime is a fairly correct approach. If suddenly the attacker somehow gets a link from SAS, which has the Expiry option set, then he simply cannot do anything with it, since access will be closed after the expiration date and that SAS becomes useless.

The getSAS function contains a fairly simple logic of creating a SAS object directly and forming part of the URL string with parameters. All this is done using the Windows Azure API, which is connected to the current script at the very beginning.

After finishing editing the script, do not forget to click on the Save button at the bottom of the page, otherwise all the work on the smarka.

Customer


So, we figured out the server logic and realized that there is nothing particularly difficult about it. We now have a certain URL in which Shared Access Signature is registered, and now let's see what to do with it. In the previous article, the Windows 8 application was only responsible for communicating with Windows Azure Mobile Services and WCF services, shifting the responsibility for saving binary data from blobs to other subsystems. At the same time, the application will independently save all information to the Windows Azure services.

To begin, let's create an empty application for Windows 8. I did not choose anything as a template, stopping at the Blank App. Since now the article is not about how to write applications, the interface and functionality of the program will be at the minimum sufficient level. In other words - no frills, but it works.

From the elements of the interface on the main page of the application, I propose to place two buttons, a text field and a container for images, where we will place the images received from the camera. I have it all look something like this:

Program Interface for Windows 8

It is necessary to repent and apologize a bit to all designers and people with a good sense of taste - the application was made not for use, but for demonstration. Accordingly, the code will also be without any frills - neither MVVM, nor other cool stuff. Three methods, but everything is clear.

Let's start with the fact that we define a class that will correspond to the Picture table in Mobile Services:
public class Picture { public int Id { get; set; } [DataMember(Name = "description")] public string Description { get; set; } [DataMember(Name = "fileName")] public string FileName { get; set; } [DataMember(Name = "imageurl")] public string ImageUrl { get; set; } } 

This is a simple class in which Id must be a field / property. The remaining properties are converted to similar fields in the table. The DataMember attribute helps to explicitly indicate the name of the table field into which a particular class property should turn.

Next, the method is responsible for obtaining images from the camera and display it on the screen:
  private async void ButtonPhotoClick(object sender, RoutedEventArgs e) { //     CameraCaptureUI cameraCapture = new CameraCaptureUI(); _file = await cameraCapture.CaptureFileAsync(CameraCaptureUIMode.PhotoOrVideo); BitmapImage bitmapImage = new BitmapImage(); //    ,     FileRandomAccessStream stream = (FileRandomAccessStream)await _file.OpenAsync(FileAccessMode.Read); bitmapImage.SetSource(stream); Photo.Source = bitmapImage; } 


Here, too, everything is simple. Whoever is familiar with the development for Windows 8 (WinRT), he will immediately understand what is happening here. And who does not know - he will guess. First, we ask the camera for a photo or video (by the way, the video can also be transferred to the BLOB storage without any problems), and then we receive the stream from the received file, write it in a bitmap and output it to the application form. Yes, and do not forget that to work with the camera in Windows 8, it is necessary, firstly, to register in the application manifest, that we are generally going to do this in principle, and secondly, to get permission from the user to access the device. If any of these conditions is not met, the code above will fail with an error, because nothing is written in _file.

Well, the only thing left for the snack is to write the received data to the Mobile Service table, get Shared Access Control from it and write the file to the cloud storage. It sounds difficult, but in fact - a few lines of code:
  private async void ButtonSaveClick(object sender, RoutedEventArgs e) { var picture = new Picture(); picture.Description = Description.Text; picture.FileName = _file.Name; //     Mobile Service var table = App.MobileService.GetTable<Picture>(); await table.InsertAsync(picture); var containerName = "mypictures"; //     using (var fileStream = await _file.OpenStreamForReadAsync()) { await UploadBlob(fileStream, picture.FileName, picture.ImageUrl, containerName); } //  SAS  URL  picture.ImageUrl = picture.ImageUrl.Substring(0, picture.ImageUrl.IndexOf('?')); await table.UpdateAsync(picture); } public static async Task UploadBlob(Stream fileStream, string fileName, string blobUrl, string containerName) { fileStream.Position = 0; var sasUri = new Uri(blobUrl); //  SAS  URL  StorageCredentials cred = new StorageCredentials(sasUri.Query.Substring(1)); //   CloudBlobContainer container = new CloudBlobContainer(new Uri(string.Format("https://{0}/{1}", sasUri.Host, containerName)), cred); //   BLOB CloudBlockBlob blobFromSASCredential = container.GetBlockBlobReference(fileName); //   await blobFromSASCredential.UploadFromStreamAsync(fileStream.AsInputStream()); } 

Let's go in order. The ButtonSaveClick method is called when the Save button is clicked. In it, we first form a Picture object, filling it with a value from the description field and the name of the image file. Then begins work with Windows Azure. We need to get the Picture table from Mobile Services and insert a new entry into it. As you can see, this is done in two lines. Then work with the BLOB repository. Immediately after the new entry was inserted into the table, the Image object's ImageUrl property changed to the picture object, to which the URL of the future blob was entered, with the Shared Access Signature added to it. With this URL, we can now access Blob Storage without knowing its name and Primary Key.

Working with the storage is moved to a separate, but also a small method UploadBlob. All the necessary actions fit into four simple steps. First we get the Shared Access Signature from the URL of the image, which is passed as a query parameter. Then, using this SAS, we get a container with which to work. Then, in the same way, we get a blob by its name, and finally, we load the binary image data from the stream straight into Azure Blob Storage.

Yes, I forgot to mention that in order to work with Blob Storage in Windows 8, a library is needed, which can be found here . In NuGet, I did not find this, so you need to connect manually. But I think that soon it will change.

Conclusion


In this article, I tried to visually show how you can work with data in Windows Azure from Windows 8 mobile applications more easily, reliably and without additional infrastructure layers using Windows Azure Mobile Services and Shared Access Signature. By and large, all the logic for writing / extracting data from a table or blob storage fits into a couple of code strings, which greatly simplifies life when you need to get the result of your work as quickly as possible. For independent developers and startups, this feature will greatly help in a successful start and will save you from the extra headache.

PS This article was partially based on official source code examples for working with Mobile Services and Shared Access Signature. You can familiarize yourself with this example here: http://code.msdn.microsoft.com/windowsapps/Upload-File-to-Windows-c9169190

Source: https://habr.com/ru/post/167065/


All Articles