Accessing blobs in private container without Shared Access Secret key
Is there any way to access blobs in private blob container without Shared Access Secret key ? i mean any User / Role based security or domain level security i.e only our domain should be able to access blobs in private container etc.
Actually i don't want to append SAS key after each blob url to access it, i want my container to be private and also i want to access each blob in that container without SAS key
any way currently available or planned in future release ?
Hi Yazeem,
As for now, Azure Blob Service does not supports User / Role based or domain level access control. If you don't want to SAS key, you may want to create a http handler in a web role to serve these private content. Please refer to a related thread (http://social.msdn.microsoft.com/Forums/en-US/windowsazuredata/thread/dbfb9d13-d463-4461-b51f-466261617cb7):
You can create a http handler to serve and secure files from blob storage. When the browser send a request to your service viahttp://xxx.cloudapp.net/courses/index.html or http://xxx.cloudapp.net/courses/style.css, it will be actually served by your own http handler. The http handler will get the actual file content (no matter it is a html, js or image file) from blob storage and return the content. By using this way, we can protect the http handler using the the built-in ASP.NET authorization and authentication functionality. Or you can use your own way to authenticate users as you have full control of the http handler.
If you have questions regarding serving blob storage using http handler, please let me know.
Thanks.
Thanks Wengchao Zeng for your reply,
I have tried both HttpHandler and HttpModule to capture the requests send to azure blob but they capture only incoming request to application.
How to capture outgoing request to azure blob ?
Hi Yazeem,
Thanks for your response.
May I ask you what you mean by "outgoing request"?
Thanks,
Hi,
From "outgoing request", i mean to say the request that is send by Web Role application to azure Blob storage.
I created HttpModule in my WebRole application, whenever i access any page in my application, i captures page requests and its associated data requests like requests for css, javascripts, images etc.
But if i access azure blob data in event of a button , HttpModule only captures the event request. It does not capture the request it (webRole) makes to blob storage.
You'll have to have the requests served by your application and use that as a proxy for the data in blob storage.
Eg the request comes into the application, the application pulls the data from blob storage and sends it back to the client
Hi Yazeem,
If I understood correctly, it seems that you have met your original requirement "accessing blobs in private blob container without Shared Access Secret key". Now the question becomes that you want to capture the request when the web role accesses blob storage.
HttpModule is used to capture the request to pages, not the outgoing request. Why do you want to capture the outgoing request? As the outgoing request is made by your code, you can implement access control in your own code before accessing blob storage.
Thanks,
Hello Wengchao Zeng,
Thanks for your help.
Actually i have stored eLearning courses on Blob storage, each container will be a course, all items of that course (xml,, Js, css, images etc.) are stored in that container as Block blob.
This container is private and can be accessed by SAS key. When i send a request to main page of course with SAS key appended at the end of its url.
That main page loads sucessfully but the js, css, xml files which this page accesses are unable to load because SAS key is not appended to their URL automatically.
HttpModule does not capture the request made to resources like js,xml, etc which course wants to load. we only access the main page of that course and rest items will be loaded / unloaded by course.
That's the reason why i am asking that whether there is any other mechanism like User / Role based security or domain level security.
Hi Yazeem,
> That main page loads sucessfully but the js, css, xml files which this page accesses are unable to load because SAS key is not appended to their URL automatically.
If the main page is served by a http handler and the js, css, xml files are linked using relative address, these files will also be served by the http handler too. For example, if the http handler serves a page in address http://xxx.cloudapp.net/blobproxy/index.html and the page links to a script file using tag <script src="myscript.js"></script>, actually the browser will use address http://xxx.cloudapp.net/blobproxy/myscript.js to access the script file. So the solution is to create a http handler to serve all requests to address http://xxx.cloudapp.netb/blobproxy/*.
For test purpose, I made this sample. Please add a class file BlobProxy.cs to your web role project:
using System; using System.Web; using Microsoft.WindowsAzure.StorageClient; using Microsoft.WindowsAzure; namespace WebApplication2 { public class BlobProxy : IHttpHandler { // Please replace this with your blob container name. const string blobContainerName = "files"; public bool IsReusable { get { return false; } } public void ProcessRequest(HttpContext context) { // Get the file name. string fileName = context.Request.Path.Replace("/blobproxy/", string.Empty); // Get the blob from blob storage. var storageAccount = CloudStorageAccount.DevelopmentStorageAccount; var blobStorage = storageAccount.CreateCloudBlobClient(); string blobAddress = blobContainerName + "/" + fileName; CloudBlob blob = blobStorage.GetBlobReference(blobAddress); // Read blob content to response. context.Response.Clear(); try { blob.FetchAttributes(); context.Response.ContentType = blob.Properties.ContentType; blob.DownloadToStream(context.Response.OutputStream); } catch (Exception ex) { context.Response.Write(ex.ToString()); } context.Response.End(); } } }
Then please add this http handler to web.config file:
<configuration> <system.webServer> <handlers> <add name="BlobProxy" verb="*" path="/blobproxy/*" type="WebApplication2.BlobProxy"/> </handlers> </system.webServer> </configuration>
Before running the project, please replace blobContainerName with your own blob container that contains both html and related files. Then start debugging the Azure service project and then you can use the following address to access the page:
http://127.0.0.1:[port number]/blobproxy/[page name]
I above sample does not work for you, please let me know.
Thanks.
Hey Wengchao,
I dont seem to get the required result with the above code. Here is what I have done to access the .xml file that is stored in blob.
Imports System.Web
Imports Microsoft.WindowsAzure.StorageClient
Imports Microsoft.WindowsAzure
Namespace WebApplication
Public Class BlobProxy
Implements IHttpHandler
' Please replace this with your blob container name.
Const blobContainerName As String = "eldata"
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
' Get the file name.
Dim fileName As String = context.Request.Path.Replace("/BlobProxy/", String.Empty)
' Get the blob from blob storage.
Dim storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString")
Dim blobStorage = storageAccount.CreateCloudBlobClient
Dim blobAddress As String = blobContainerName & "/" & fileName
Dim blob As CloudBlob = blobStorage.GetBlobReference(blobAddress)
Dim bool As Boolean = EL_ComFun.BlobExists(blob)
' Read blob content to response.
context.Response.Clear()
Try
blob.FetchAttributes()
context.Response.ContentType = blob.Properties.ContentType
blob.DownloadToStream(context.Response.OutputStream)
Catch ex As Exception
context.Response.Write(ex.ToString())
End Try
context.Response.[End]()
End Sub
End Class
End Namespace
------------------------------------------------------------------------------------------------
and after this i try to access the xml file in an aspx page by providing the link
dim str as String = "http://593b7d2f4e754850a34dd48167619f0a.cloudapp.net/BlobProxy/DicFiles/L5_CD1/9MGAA2_E/9MGAA2.xml"
ds.ReadXml(flnmXML)
This reading of xml file throws an error "The remote server returned an error: (500) Internal Server Error."
I also want to know where to reference the class file that i created (BlobProxy.vb)
Where am I going wrong? Could you please correct me to solve this problem ?
Regards
Sandeep
|