I worked on a customer machine and used the identity and access tool to enable Identity Federation. When I looked at the config that was produced by the tool I saw something strange.
Instead of the good old configuration:
<issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry,
System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<trustedIssuers>
<add thumbprint="9B74CB2F320F7AAFC156E1252270B1DC01EF40D0" name="LocalSTS" />
</trustedIssuers>
</issuerNameRegistry>
The tool produced the following:
<issuerNameRegistry type="System.IdentityModel.Tokens.ValidatingIssuerNameRegistry,
System.IdentityModel.Tokens.ValidatingIssuerNameRegistry">
<authority name="LocalSTS">
<keys>
<add thumbprint="9B74CB2F320F7AAFC156E1252270B1DC01EF40D0" />
</keys>
<validIssuers>
<add name="LocalSTS" />
</validIssuers>
</authority>
</issuerNameRegistry>
Well it turns out that identity and access tool was upgraded and the new issuerNameRegistry configuration provide better token validation.
More details can be found at Vittorio Bertocci blog.
The update can be found here.
Hope this helps
Manu
Today I spoke about web identities and about Azure data sync.
In the web identities talk I spoke about the identity concept and about the open ID, SAML and OAuth standards.
In the Azure data sync talk I spoke about the value of sync, the Microsoft synchronization framework (MSF) and the Azure data sync service (which is based on MSF)
Tomorrow I will speak about cryptography in .Net and explore different types of encryption algorithms and signing APIs.
You can find the slide deck here:
You can find the code demo of the cryptography talk here.
Hope you enjoyed the show
Manu
Until recently, you could only sign up for a new Windows Azure subscription using your Microsoft account (LiveID) It means that your administration account is governed by a private user account.
This is a major security threat.
- The account credentials are simple user name and password (which could be easily stolen)
- No “Multi factor authentication” is possible
- No policy and management is enforced on the administration identity
All this is changing now with Windows Azure Active Directory (WAAD)
Now you can Sign-In to windows Azure as an organization !!!
After you sign up to Azure as an organization, a cloud based tenant is automatically provisioned in WAAD to represent your organization.
Once this tenant has been created, an admin can then issue organizational accounts to each of its employees and assign licenses that will enable them to login to Windows Azure.
The tenant identities can be synchronized with your on-premises AD and managed as a directory in the cloud.
It means that you can use your home authentication method (for example: smart-card with a pin number) to authenticate to Azure. You can revoke users from a single location and enforce password policies.
The following login page can be used to sign-in to azure with your organization account.
A good place to start learning about WAAD can be found here.
Enjoy
Manu
It is common to upload / transfer certificates as base64 strings.
A common example is Azure Management API Add Service Certificate.
To encode a certificate all you have to do is simply encode the certificate file.
var encodedClientCert = Convert.ToBase64String(File.ReadAllBytes("Client.Cer"));
To create a certificate out of base64 string is as easy:
string str = "base64string representing a certificate";
string psw = "password for certificates with a private key";
var cert = new X509Certificate2(Convert.FromBase64String(str), psw);
Hope this helps
Manu
It you will try to upload a large file (2Mb and larger) to blob storage it is likely that you will get the following timeout exception: “StorageServerException : Operation could not be completed within the specified time.”
The solution is to do things in parallel.
Fortunately blob storage has a simple API for parallel upload.
blobClient.ParallelOperationThreadCount = 20;
To use it it is required to open the max number of outgoing connection using
ServicePointManager.DefaultConnectionLimit
The following method will demonstrate that:
Code Snippet
- public static void LoadLargeBlob(string storageAccountName, string storageAccountKey)
- {
- ServicePointManager.DefaultConnectionLimit = 20;
-
- string storageConnectionString = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
- storageAccountName, storageAccountKey);
-
- CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);
- var blobClient = account.CreateCloudBlobClient();
- blobClient.ParallelOperationThreadCount = 20;
- var container = blobClient.GetContainerReference("myContainer");
- container.CreateIfNotExist();
-
- var blob = container.GetBlobReference("largeblob");
- blob.UploadFile("largefile");
- }
Hope this helps
Manu
I wrote a nice helper class that helps me find certificates installed on my machine.
Here is the code:
Code Snippet
- public static class CertificateHelper
- {
- public static X509Certificate2 FindCertificateByThumbprint(string certificateThumbprint)
- {
- var res = FindCertificateByThumbprint(certificateThumbprint, new X509Store(StoreName.My, StoreLocation.CurrentUser)) ??
- FindCertificateByThumbprint(certificateThumbprint, new X509Store(StoreName.My, StoreLocation.LocalMachine));
-
- if (res == null)
- throw new Exception(string.Format("No certificate found with the thumbprint {0} ", certificateThumbprint));
-
- return res;
- }
-
-
- public static X509Certificate2 FindCertificateByName(string subjectName)
- {
- var res = FindCertificateByName(subjectName, new X509Store(StoreName.My, StoreLocation.CurrentUser)) ??
- FindCertificateByName(subjectName, new X509Store(StoreName.My, StoreLocation.LocalMachine));
-
- if (res == null)
- throw new Exception(string.Format("No certificate found with the subjectName {0} ", subjectName));
-
- return res;
- }
-
- private static X509Certificate2 FindCertificateByThumbprint(string certificateThumbprint, X509Store store)
- {
- X509Certificate2Collection certCollection = null;
-
- // Open the certificate store for the current user.
- store.Open(OpenFlags.ReadOnly);
-
- // Find the certificate with the specified thumbprint.
- certCollection = store.Certificates.Find(
- X509FindType.FindByThumbprint,
- certificateThumbprint,
- false);
-
- // Close the certificate store.
- store.Close();
-
- // Check to see if a matching certificate was found.
- if (0 == certCollection.Count)
- return null;
-
- // A matching certificate was found.
- return certCollection[0];
-
- }
-
-
- private static X509Certificate2 FindCertificateByName(string subjectName, X509Store store)
- {
- X509Certificate2Collection certCollection = null;
-
- // Open the certificate store for the current user.
- store.Open(OpenFlags.ReadOnly);
-
- // Find the certificate with the specified thumbprint.
- certCollection = store.Certificates.Find(
- X509FindType.FindBySubjectDistinguishedName,
- subjectName,
- false);
-
- // Close the certificate store.
- store.Close();
-
- // Check to see if a matching certificate was found.
- if (0 == certCollection.Count)
- return null;
-
- // A matching certificate was found.
- return certCollection[0];
-
- }
- }
Hope this helps
Manu
If you want to use a client certificate as a client credential you have to make sure the role machine knows your client’s certificate issuer. If your client certificate was created by a self signed CA (Certificate Authority) it means that you have to upload the CA itself to the role’s trusted root certificate authority certificate store.
The problem is that for some reason uploading a certificate to the trusted root certificate authority certificate store is NOT supported for web roles.
The solution is simply: Upload the CA certificate to the “My” certificate store and then copy it manually to the trusted root certificate authority certificate store.
Here is the code that execute the copy certificate process. I run this code from WebRole.cs
private void InstallCACertInRootCA(string thumbprint)
{
try
{
var cert = CertificateHelper.FindCertificateByThumbprint(thumbprint);
X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(new X509Certificate2(cert));
store.Close();
}
catch (Exception ex)
{
Logger.Error(ex);
}
}
The certificateHelper is a simple helper I wrote to load the certificate from the “My” certificate store. Once I have the certificate I just copy it to the Root Certificate Authorities store. (I will post the details in a future post)
One last thing: The code has to run in elevated mode.
<Runtime executionContext="elevated">
Hope this helps
Manu
A simple method to authenticate customers is by using client certificates. Smart card and enterprise customers are just two basic scenarios.
Lets describe how to implement client certificate authentication in a simple Web API service deployed in Windows Azure.
The first thing we need to do is to establish an SSL channel. Client certificates can only be attached to a SSL request. To do that we need to create an SSL certificate and sign it by a trusted CA (Certificate Authority). We can create a certificate request using IIS and send it to the CA. (see figure)
or create a self signed CA, install it to our trusted certificate store and then use it to create our SSL certificates.
Lets create a CA certificate:
@echo off
echo delete old CA certificate
certutil -delstore root "My CA"del MyCA.*
echo create My CA certificate
makecert -r -pe -n "CN=My CA" -ss CA -a sha1 -sky signature -cy authority -sv myCA.pvk myCA.cer
pvk2pfx -pvk myCA.pvk -spc myCA.cer -pfx myCA.pfx -po password echo install My CA certificatecertutil.exe -addstore root myCA.cer Now its time to create a new SSL certificate using our CA:
Echo off
del server.*
Echo Create SSL certificate
makecert -pe -n "CN=server" -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1
-ic myCA.cer -iv myCA.pvk –sp "Microsoft RSA SChannel Cryptographic Provider"
-sy 12 -sv server.pvk server.cer
pvk2pfx -pvk server.pvk -spc server.cer -pfx server.pfx -po 123456
The final step is to create a client certificate using our CA. This certificate will be used by clients to authenticate.
echo off
echo delete existing Client certificate
del ClientCert.*certutil -delstore my "ClientCert"
echo create Client certificate
makecert -pe -n "CN=ClientCert" -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.2
-ic myCA.cer -iv myCA.pvk -sv ClientCert.pvk ClientCert.cerpvk2pfx
-pvk ClientCert.pvk -spc ClientCert.cer -pfx ClientCert.pfx -po password
certutil -addstore -user my ClientCert.cer
Now we need to configure IIS to accept our client certificates. By default IIS will ignore incoming client certificates and the certificates will not be accessible in our code.
This is very simple on a on-premises server yet in Azure it can be quite tricky. As Azure developers we are used to configure our machine using start up task. The problem is that SSL Settings configurations are enforced on existing web sites. When startup tasks are running the web site of our application was not yet created so the tasks will fail. The solution is to configure IIS in code. Fortunately the NuGet package “Microsoft.Web.Administration” provides all the API we need.
using (var serverManager = new ServerManager())
{
try
{
var siteName = RoleEnvironment.CurrentRoleInstance.Id + "_Web";
var config = serverManager.GetApplicationHostConfiguration();
var accessSection = config.GetSection("system.webServer/security/access", siteName);
accessSection["sslFlags"] = @"SslNegotiateCert";
serverManager.CommitChanges();
}
catch (Exception ex)
{
...
}
}
Calling this code from our role’s OnStart method will do the job as long as we run in elevated execution:
<Runtime executionContext="elevated">
Now we need to upload both CA certificate (to trusted certificate authorities) and our SSL certificate (to the personal store) and configure an SSL endpoint
Details about uploading and installing the CA certificate in the web role machine can be found in a post I wrote here.
The certificates must be uploaded independently to the hosted service using the portal or the management API.
Now we can create a delegation handler that will authenticate all incoming requests and plug it into the ASP.NET WEB API pipeline.
public class CertificateAuthHandler : DelegatingHandler
{
public CertificateAuthHandler()
protected override System.Threading.Tasks.Task<HttpResponseMessage>
SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
X509Certificate2 certificate = request.GetClientCertificate();
if (certificate == null || !CertificateValidator.IsValid(certificate))
{
Logger.Warn("No certificate was found or it is invalid");
return Task<HttpResponseMessage>.Factory.StartNew(
() => request.CreateResponse(HttpStatusCode.Unauthorized));
}
Thread.CurrentPrincipal = CertificateValidator.GetPrincipal(certificate);
return base.SendAsync(request, cancellationToken);
}
}
to plug the delegation handler let us update WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null );
config.EnableQuerySupport();
config.MessageHandlers.Add(new CertificateAuthHandler());
}
}
That’s it.
Now we are ready to call our service on an SSL REST endpoint which is protected by a client certificate.
Hope this helps
Manu
On December 21th Microsoft released important improvements for its Azure services which include the following:
- Mobile Services: Job scheduler support, Europe Region Support, Command Line Support
- Web Sites: Ability to scale up to 6 shared instances and 10 reserved VMs, integrated source control in custom create wizard
- SQL Data Sync: Now supported in the new HTML portal
- ACS Management: Now supported in the new HTML portal
- Media Services: New job and task management, blob storage support, reserved compute
- Virtual Network: Simplified workflow for custom scenarios
- Windows Azure Store: Now available in more countries
- Subscription Filtering Support
More information can be found at Kirill Gavrylyuk blog post:
Enjoy
Manu
Visual Studio has an Identity and Access tool extension which enables simple integration of claim based identity authentication into a web project (WCF and ASP.Net)
It turns out that the tool depends on Windows Identity Framework (WIF) 4.5 which was integrated into the .Net framework and is not compatible with WIF 4.0.
For .Net 4.5 only applications you will see the following when you right click the project.

“Enable Windows Azure Authentication” integrate your project with Windows Azure Active Directory (WAAD). “Identity and Access” integrate your project with Windows Azure Access Control Service (ACS) or any other STS (Identity Provider) including a test STS which will run on your development machine.
If you install the Identity and Access tool extension and you don’t see the above option just change your framework to 4.5.
Manu
Few days ago the new portal was upgraded. The service bus was maid available (and few other new features) but the CTP announcements and the link to the previous portal was removed.
Unfortunately as for today not all Azure features are available in the new portal, so the previous portal is still required. For example to use ACS or Data Sync we have to use the previous portal.
To access the previous portal click on your name:

Then a new menu will be opened, and a nice menu item will point you to the previous portal.

Enjoy
Manu
I wanted to run a concurrency profiling on my app so I activated the performance wizard and chose the last option (concurrency) but the results where nothing like I expected. The report I got looked similar to the sampling report presenting information about contention.

I looked around and found that the good old concurrency profiling is now called “Concurrency Visualizer”.
Click it and you’ll get all the concurrency reports.

Enjoy
Manu
Unit testing is not easy. One of the greatest challenges is to identify external dependencies and provide mock objects and behaviors. Few years ago Microsoft Research came out with an infrastructure called “moles” designed to solve this problem. With moles is was extremely easy to inject mock behavior and functionality to existing code (including code we don’t own such as the .net framework itself)
Well In Visual Studio 2012 moles was adopted and introduced as the “Fake” feature.
Now all we need to do to inject mock behavior to external code is create a fake assembly by right clicking the referenced assembly and choosing “Add Fake Assembly”. Now all left to do is to inject mock behavior to the new mock objects and use it in our test.

The details about using the fake objects and injecting mock functionality can be found here.
Enjoy
Manu
A customer asked me if it is possible to connect cloud services to azure virtual network.
When creating a new virtual machine we specify the network to be used but when creating a new cloud service the portal does not provide a method to connect the new cloud service to an existing virtual network.
Well It is possible !!!
Michael Washam wrote a nice blog about it.
The Idea is to put NetWorkConfiguration in the config file (.cscfg) of your deployment.
Enjoy
Manu
A customer asked me how to dynamically discover the identity providers of a certain namespace in ACS.
The request is simple:
Let’s assume we have an application (RP) in http:\\localhost\myApp
If will send the following request to acs:
https://xxx.accesscontrol.windows.net:443/v2/metadata/IdentityProviders.js?protocol=wsfederation&realm=http%3a%2f%2flocalhost%2fmyapp%2f&version=1.0
we will get the following json in the response
[{"Name":"Windows Live™ ID","LoginUrl":"https://login.live.com/login.srf?wa=wsignin1.0&wtrealm=https%3a%2f%2faccesscontrol.windows.net%2f&wreply=https%3a%2f%2fxxx.accesscontrol.windows.net%3a443%2fv2%2fwsfederation&wp=MBI_FED_SSL&wctx=cHI9d3NmZWRlcmF0aW9uJnJtPWh0dHAlM2ElMmYlMmZsb2NhbGhvc3Q1","LogoutUrl":"https://login.live.com/login.srf?wa=wsignout1.0","ImageUrl":"","EmailAddressSuffixes":[]},
{"Name":"Google","LoginUrl":"https://www.google.com/accounts/o8/ud?openid.ns=http%3a%2f%2fspecs.openid.net%2fauth%2f2.0&openid.mode=checkid_setup&openid.claimed_id=http%3a%2f%2fspecs.openid.net%2fauth%2f2.0%2fidentifier_select&openid.identity=http%3a%2f%2fspecs.openid.net%2fauth%2f2.0%2fidentifier_select&openid.realm=https%3a%2f%2fxxx.accesscontrol.windows.net%3a443%2fv2%2fopenid&openid.return_to=https%3a%2f%2fxxx.accesscontrol.windows.net%3a443%2fv2%2fopenid%3fcontext%3dcHI9d3NmZWRlcmF0aW9uJnJtPWh0dHAlM2ElMmYlMmZsb2NhbGhvc3QmcHJvdmlkZXI9R29vZ2xl0&openid.ns.ax=http%3a%2f%2fopenid.net%2fsrv%2fax%2f1.0&openid.ax.mode=fetch_request&openid.ax.required=email%2cfullname%2cfirstname%2clastname&openid.ax.type.email=http%3a%2f%2faxschema.org%2fcontact%2femail&openid.ax.type.fullname=http%3a%2f%2faxschema.org%2fnamePerson&openid.ax.type.firstname=http%3a%2f%2faxschema.org%2fnamePerson%2ffirst&openid.ax.type.lastname=http%3a%2f%2faxschema.org%2fnamePerson%2flast","LogoutUrl":"","ImageUrl":"","EmailAddressSuffixes":[]},{"Name":"Yahoo!","LoginUrl":"https://open.login.yahooapis.com/openid/op/auth?openid.ns=http%3a%2f%2fspecs.openid.net%2fauth%2f2.0&openid.mode=checkid_setup&openid.claimed_id=http%3a%2f%2fspecs.openid.net%2fauth%2f2.0%2fidentifier_select&openid.identity=http%3a%2f%2fspecs.openid.net%2fauth%2f2.0%2fidentifier_select&openid.realm=https%3a%2f%2fxxx.accesscontrol.windows.net%3a443%2fv2%2fopenid&openid.return_to=https%3a%2f%2fxxx.accesscontrol.windows.net%3a443%2fv2%2fopenid%3fcontext%3dcHI9d3NmZWRlcmF0aW9uJnJtPWh0dHAlM2ElMmYlMmZsb2NhbGhvc3QmcHJvdmlkZXI9WWFob28h0&openid.ns.ax=http%3a%2f%2fopenid.net%2fsrv%2fax%2f1.0&openid.ax.mode=fetch_request&openid.ax.required=email%2cfullname%2cfirstname%2clastname&openid.ax.type.email=http%3a%2f%2faxschema.org%2fcontact%2femail&openid.ax.type.fullname=http%3a%2f%2faxschema.org%2fnamePerson&openid.ax.type.firstname=http%3a%2f%2faxschema.org%2fnamePerson%2ffirst&openid.ax.type.lastname=http%3a%2f%2faxschema.org%2fnamePerson%2flast","LogoutUrl":"","ImageUrl":"","EmailAddressSuffixes":[]}]
Now we can use (http get) the LoginUrl of each provider which will send us directly to its login page.
If we call ACS with: https://xxx.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2flocalhost%2fmyapp%2f
We will get the good old identity providers list from ACS from which the user can choose his identity provider.
these links can be easily found in the portal application integration –> login page integration

Enjoy
Manu
More Posts
Next page »