Chef with PowerShell Scripts – Accessing Encrypted Data Bag Items

Chef data bags provide the ability to store unstructured data in JSON format. Data bags can be accessed from the chef server and can store global variables, or variables specific to an environment.
One of the great features of Chef data bags is the ability to encrypt information, such as passwords, to avoid storing sensitive data as plain text.
Data bag items can be encrypted using shared secret encryption, and then decrypted using the same secret file from a chef recipe. The items can also be decrypted with knife and used in a shell script. Here is how:

Creating passwords data bag:

mkdir data_bagspasswords
knife data bag create passwords

 
Create anmy_password.json file with the following information in passwords directory:

{
  "id": "the_password",
  "password": "[email protected]"
}

 
Create secret file using PowerShell:

$key = New-Object byte[](512)
$rng = [System.Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($key)
[Convert]::ToBase64String($key) | Out-File " C:secretsmy_secret" -encoding "UTF8"
[array]::Clear($key, 0, $key.Length)

 
Encrypt items in data bag
To encrypt a data bag item using the secret file:

knife data bag from file passwords my_password.json --secret-file C:secretsmy_secret

 
To verify the encryption:

knife data bag show passwords the_password

The output should look like this:
ps output
 
Decrypt items in data bag with knife:

knife data bag show passwords the_password--secret-file C:secretsmy_secret

 
To get the password from the data bag and decrypt it into a variable:

$json = knife data bag show passwords the_password --secret-file C:secretsmy_secret -F json
$password = (($json -join "`n") | ConvertFrom-Json).password

 
Now you have $password variable holding the value [email protected]
Happy cooking!

How to Configure User Access to Azure Resources

One of the great features of the “new” Azure Portal is granular user access. You can provide role-based access to entire subscriptions, resource groups or even specific resources. RBAC allows you to ensure that every employee in your organization has the appropriate level of access to the appropriate resources.

How do you set this up?
Here is a step-by-step walk through with pictures:

Add access to entire subscription

1. Sign in to the new portal https://ms.portal.azure.com/
2. Click Browse All => Subscriptions
3. Choose the subscription you need
4. Click Users

ua1

5. In Users pane click Add
6. Click Select a Role
7. Choose the appropriate role
8. Click OK in the Add access pane

ua2

9. In the Add Access pane click Add Users
10. Insert a valid Microsoft Account (former Live ID) email or choose from the list of users you have already added

ua3

Add access to a resource group

1. Sign in to the new portal https://ms.portal.azure.com/
2. Click Browse All => Resource Groups
3. Select the resource group you need
4. Click All Settings
5. In Settings pane click Users
6. Follow steps 6-10 from paragraph 1

ua4

Add access to a specific resource

1. Sign in to the new portal https://ms.portal.azure.com/
2. Browse to the specific resource you need
3. Click All Settings
4. In Settings pane scroll down and click Users
5. Follow steps 6-10 from paragraph 1

ua5

Clone Git Tag via PowerShell

Install Git

If you don’t already have Git for Windows:
Download Git for Windows from https://msysgit.github.io/
Choose “Use Git from the Windows Command Prompt” during the installation – this will add Git to your PATH
git install

Alternatively you can manually add Git to your PATH:
Go to System Environment Variables => Advanced => Environmental Variables.
Find path in the variables list and hit edit.
Add the path to Git executable on your machine. In my case it is C:Program Files (x86)Gitcmd

Now Git commands will be recognized in PowerShell on your machine.

Clone the tag

Open PowerShell
Clone repo via https:

git clone https://path/repo.git

 
List available tags:

git tag -l

 
Checkout the tag:

git checkout tag_name

Enjoy!

Prompt for Sign-In on 401 – Unauthorized Errors in MVC App with Azure Active Directory Using WS Federation

Following my post on Partial Authentication with AAD I am going to elaborate on how to prompt the user to sign into the application instead of throwing a 401 – unauthorized error.

First step is to add HTTP error 401 redirect to IIS configuration in Web.config

<system.webServer>
    <httpErrors existingResponse="Replace" 
			defaultResponseMode="Redirect" errorMode="Custom">
      <remove statusCode="401"/>
      <error statusCode="401" responseMode="ExecuteURL" path="/Account/SignInRedirect"/>
    </httpErrors>
	...
<system.webServer>

Note that the responseMode is ExecuteURL (and not Redirect). This allows the requested URL to be passed through to the SignInRedirect method.

Now all we need is to add proper redirect conditions to our /Account/SignInRedirect method

public ActionResult SignInRedirect()
{
	if (Request.IsAuthenticated)
	{
		// The user is signed in 
		// but does not have permissions to access a specific URL
		return RedirectToAction("InsufficientPermissions", "Account");
	}

	// Redirect to home page after signing in.	
	WsFederationConfiguration config = 
		FederatedAuthentication.FederationConfiguration.WsFederationConfiguration;
		
	string callbackUrl = Url.Action("Index", "Home", 
			routeValues: null, protocol: Request.Url.Scheme);
	
	//The URL the user originally requested is passed in Request.RawUrl
	if (Request.RawUrl != null)
	{
		callbackUrl = Request.RawUrl;
	}

	SignInRequestMessage signInRequest = 
		FederatedAuthentication.WSFederationAuthenticationModule
		.CreateSignInRequest(
			uniqueId: String.Empty,
			returnUrl: callbackUrl,
			rememberMeSet: false);

	signInRequest.SetParameter("wtrealm", IdentityConfig.Realm ?? config.Realm);
	return new RedirectResult(signInRequest.RequestUrl.ToString());
}

 

There are 2 main use cases this method aims to cover:

A non-authenticated user gets tries to access a URL that requires authorization

When a non-authenticated user tries to access a URL that is behind an [Authorize] attribute she will get a 401 – Unauthorized error. This error will be redirected by IIS to the path specified in httpErrors configuration, in our case /Account/SignInRedirect. The original URL will be passed on as well in Request.RawUrl. The sign in method will then attempt to sign the user in, and if the sign in is successful redirect her to the originally requested URL.

An authenticated user tries to access a URL he does not have access to

In this case the first if clause of the sign in method will be activated, and the user will be redirected to a custom error page. You can inform the user that she does not have permissions to view the page, or craft any other custom error message. You could also choose to redirect the user back to home page. The one thing you should _not_ do is redirecting the user back to the Request.RawUrl, as this will result in an infinite redirect loop.
Another possible behavior in this case would be to prompt the user to sign in with an account that does have access to the requested URL. This behavior is, however, not typical for AD scenarios, where it is unlikely that a single user has access to multiple AD accounts.

Why am I separating the /Account/SignInRedirect from the regular /Account/SignIn method?
The reason is the case when the user tries to sign in via /Account/SignIn, and her credentials are already stored by the browser. In this case the user should be redirected to home, rather than hitting the insufficient permissions error page. Please view the original post for the /Account/SignIn method implementation.

Generic Type-Safe Method to Retrieve Values from App Settings

Following my post from yesterday, I had to publish this little method that helps you retrieve values from your appSettings in a type-safe manner.

I simply love things like that – just a few lines of code make sure you won’t have to worry about type casting in the rest of your application!

using System;
using System.Configuration;

namespace MyApp.Domain.Helpers
{
	public static class ConfigHelper
	{
		public static T GetAppSetting<T>(string key)
		{
			var setting = ConfigurationManager.AppSettings[key];
			if (null == setting) return default(T);
			return (T)Convert.ChangeType(setting, typeof(T));
		}
	}
}

 
* Please note that this method will return the default value of type T if the setting key isn’t present, and throw an exception if the value is of an incorrect type. Other approaches to error handling might need to be implemented depending on your application.

And the usage:

var intValue = ConfigHelper.GetAppSetting<int>("IntValue");
var stringValue = ConfigHelper.GetAppSetting<string>("StringValue");

Custom MVC Role Authorize Attribute using App Settings

Here is a simple implementation of a custom [Authorize] attribute that uses appSettings get Role names:

The only important thing to note here is using Sytem.Web.Mvc, since the [Authorize] attribute also exists in System.Web.Http and has a slightly different implementation there.
I believe the two implementations have been unified in Asp.Net 5 / MVC 6, but that is still in preview.

using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MyApp.Web.Attributes
{
    public class RoleAuthorizeAttribute : AuthorizeAttribute
    {

        public RoleAuthorizeAttribute(params string[] roleNames)
        {
            var roles = roleNames.Select(roleName => 
			ConfigHelper.GetAppSetting<string>(roleName)).ToList();

            this.Roles = string.Join(",", roles);
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            return base.AuthorizeCore(httpContext);
        }
    }
}

Now you decorate your controllers / methods with [RoleAuthorize(“MyRoleName”)]

[RoleAuthorize("MyRoleName")]
public class MyController : Controller
{
	public ActionResult Index()
	{
		return View();
	}
}

And this is all for this post =)

Partial Authentication with Azure Active Directory with WS Federation in an MVC Application

Given: an MVC web application that is authenticated with Azure Active Directory using WS Federation.

Problem: allow non-authenticated users to access the application, restrict some of the pages to authenticated users only.

Challenge: when you start a new project in Visual Studio 2013 and choose Azure Active Directory as your Identity provider you get a setup that is pre-configured to put the entire site behind authentication.

To re-configure your application to allow non-authenticated users, you will need to do the following:

Web.config
Change the authorization snippet to allow users.

<system.web>
    <authorization>
      <allow users="*" />
    </authorization>
	...
</system.web>

 
AccountController.cs
Add the SignIn Method

public ActionResult SignIn()
{
	if (Request.IsAuthenticated)
	{
		// Redirect to home page if the user is already signed in.
		return RedirectToAction("Index", "Home");
	}
	// Redirect to home page after signing in.	
	WsFederationConfiguration config = 
		FederatedAuthentication.FederationConfiguration
			.WsFederationConfiguration;

	string callbackUrl = 
		Url.Action("Index", "Home", 
			routeValues: null, protocol: Request.Url.Scheme);
		
	SignInRequestMessage signInRequest = 
		FederatedAuthentication.WSFederationAuthenticationModule
			.CreateSignInRequest(
				uniqueId: String.Empty,
				returnUrl: callbackUrl,
				rememberMeSet: false);

	signInRequest.SetParameter("wtrealm", IdentityConfig.Realm ?? config.Realm);
	return new RedirectResult(signInRequest.RequestUrl.ToString());
}

 
Now you can decorate the appropriate controllers and/or methods with the regular MVC [Authorize] attribute to require authentication.

 
If you have multiple Reply URLs configured for your application in Azure AD, you will need to add the following setting to your Web.config transforms for different environments:

<system.identityModel.services>
	<federationConfiguration>
		<wsFederation reply="EnvironmentSpecificReplyURL" 
				xdt:Transform="SetAttributes" />
	</federationConfiguration>
</system.identityModel.services>

 
Please view my subsequent blog post on how to handle 401 – Unauthorized errors properly.

 
Bonus Tip: consider switching your application from WS Federation to the newer and shinier OpenId Connect. See samples here.

IoT Frenzy

Today everyone is talking about the internet of things, or IoT.

Did you already venture into an electronics store and purchase a Raspberry Pi , an Arduino, a couple of light, motion and temperature sensors and a bunch of little cables? (Did you know that in under 3 years the Raspberry Pi manufacturer has gone from zero to being the biggest selling UK computer manufacturer ever? The company itself couldn’t predict that these small boards will generate such excitement =) Is there a LED light on your desk that turns on every time the temperature in the room is above 75, or a little motor that starts working every time the lights are on?

I know I had to get my hands dirty!

Here is the incredibly exciting output of my Arduino Uno experiment:
IoT sensor output
Judging by the graph, my little Arduino needs some love and warms =)

Big thanks to Microsoft for this open source repository, Connect the Dots, that gives you most of the code needed to get this up and running, and a step-by-step guide on how to set things up.

This little experiment takes advantage of one of the most powerful offers of Azure platform – the Service Bus, and in particular, Event Hubs. Generally speaking, Service Bus allows you to connect a service to its consumer, leaving the consumer agnostic to the location and the details of implementation of the service. Event Hubs, in particular, provide a scalable event ingestor service that can process millions of events per second. The service allows you to process and analyze the massive amounts of data produced by your connected devices or applications, and is ideal for the IoT scenario in which you typically have many small devices transmitting large amounts of telemetry from multiple locations.

Next on ToDo list – plug the data into Machine Learning to acquire valuable insights!

SQL Azure Database SSL 3.0 Connectivity Issue in PCI Compliant Application

My team’s past 48 hours were spent in our little personal branch of hell, the one you get sent to when your application crashes for an unknown reason without any warning, and every new piece of information you discover while trying to identify the root cause is conflicting with the previous symptoms. If you manage to get past the feeling that your application was personally cursed by a vicious voodoo shaman and stay focused on the solution, I promise you will find a non-magical explanation for your problem, in this case – environmental change.

Read More (Company Blog Site)