When you going to use the Access Control Service (ACS) on the Windows Azure platform, then there are enough resources to help you. For example here. A lot of configuration has to be done, but it is do-able on the ACS website and in your application.
But deploying your Windows Azure application to the Cloud is a different cookie. Here are some steps I found the hard way.
NB It is a good practice to make the website use SSL.
1) The Windows Identity Foundation (WIF) runtime.
On the standard Windows Azure instances the WIF runtime is not there. After reading many discussions and trying it myself, a simple ‘copy local’ on the WIF assembly (Windows.Identity.dll) will not always do the trick. The best way is to install the WIF runtime during the deployment of your Windows Azure web application.
That is fairly easy. The startup task mechanism of Windows Azure makes it possible to execute a batch file and this batch file can install the runtime. The runtime can be downloaded here. There is a x86 and a x64 version available. The x64 you need for Windows Azure of course. Depending the chosen OS Family (Windows 2008 of Windows 2008 R2) you need the 6.0 or the 6.1 version. Are you developing local on Windows 7 or Windows 2008 R2 version 6.1 is also needed.
In the ServiceDefinition.csdef of the Windows Azure application add the following.
<Startup>
<Task commandLine=”startup.cmd”
executionContext=”elevated”
taskType=”simple”>
</Task>
</Startup>
Add to the webproject a file named startup.cmd. It is easier to put it in the root, if not add the path in the command above.
The startup.cmd contains:
REM WIF assembly
sc config wuauserv start= demand
wusa.exe “%~dp0Windows6.1-KB974405-x64.msu” /quiet /norestart
rem wusa.exe “%~dp0Windows6.0-KB974405-x64.msu” /quiet /norestart
sc config wuauserv start= disabled
During the deployment of the application the startup task will be executed.
2) Multiple instances
Assuming you are aware that in order to comply to the Windows Azure SLA you need at least two instances of a role. But from Windows Azure ACS you get a cookie. The cookie will be encrypted and decrypted. This will be done with the machine key of the instance. But each instance has his own machine key, so a cookie from one instance can not be read on an other instance.
The solution quite simple, make sure the encryption is done with the same key. For my domain I bought a SSL certificate and I am using this cert for encrypting. In order to make this right in the Global.asax.cs the FederatedAuthentication.ServiceConfigurationCreated method should be added.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
…
FederatedAuthentication.ServiceConfigurationCreated +=
OnServiceConfigurationCreated;
}
void OnServiceConfigurationCreated(object sender,
ServiceConfigurationCreatedEventArgs e)
{
// Use the <serviceCertificate> to protect the cookies
// that are sent to the client.
// so multiple roles do the same.
// if (e.ServiceConfiguration.ServiceCertificate == null)
// return;
Trace.WriteLine(“ServiceCertif: “,
e.ServiceConfiguration.ServiceCertificate.Thumbprint);
List<CookieTransform> sessionTransforms =
new List<CookieTransform>(
new CookieTransform[] {
new DeflateCookieTransform(),
new RsaEncryptionCookieTransform(
e.ServiceConfiguration.ServiceCertificate),
new RsaSignatureCookieTransform(
e.ServiceConfiguration.ServiceCertificate)
}
);
SessionSecurityTokenHandler sessionHandler =
new SessionSecurityTokenHandler(
sessionTransforms.AsReadOnly());
e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(
sessionHandler);
}
3) Realm
My demo site (https://cloudtest.marcelmeijer.net) all pages are visible without logging in, but in order to get to the secret page you have to sign in. The default situation after the wizard all pages will not not accessible without a sign in. To accomplish that I commented this part in the web.config.
<system.web>
<!—
<authorization>
<deny users=”?” />
</authorization>
–>
Implementing ACS is fact rather simple, but there are many nods to turn and twist in order to make it right.
And you should realize this. The Access Control mechanism Windows Azure provides is about authentication. Do you remember? Authentication, are you the one you tell you are; Authorization, what role(s) do you have the website / webapplication. ACS provides authentication. By checking username /password with one of the Identity providers.
Image may be NSFW.
Clik here to view.
The authorization should be in your own website or webapplication. The claims you get from the identity providers are tokens (pnly FaceBook), e-mail addresses (not with Windows Live), Name (not with Windows Live) and a nameidentifier. The nameidentifier can be used in your roles accounting system. If you let your users use Windows Live as a Identity provider you should ask for e-mail address and name or go with the nameidentifier back to the Windows Live services to get it.
Have fun with WIF, ACS and Windows Azure. Do you need my web.config, mail me (marcelmeijer @ planet.nl). My demo site is https://cloudtest.marcelmeijer.net.