SharePoint Intersection 2013 Talk

This was my first taste of presenting at a big name developer conference, and what a great event it turned out to be. If you attended my talk on Yammer API De­vel­op­ment I hope you found it worthwhile. Please @mention me on the Yammer Developer Network with any follow-up questions.

There were some awesome from Elijah Manor, Bill Wagner, and many others. Co-locating the conference alongside Angle Brackets and the other In­ter­sec­tion con­fer­ences allowed me to dip into relevant talks from a range of speakers I normally wouldn't be able to see.

If you are interested in more of this, the next one will be held in Orlando in April.

Tagged with yammer, cloud, javascript, sharepoint and rest.

Adding "Sign-in with Yammer" to ASP.NET MVC apps

One of the biggest pain points with enterprise web ap­pli­ca­tions is user engagement stemming from another logon to remember, and mountain of profile fields to complete. For­tu­nate­ly there are ways to improve this experience.

Sign-in with Yammer button.

Depending on the situation you might be able to take advantage of Integrated Windows Au­then­ti­ca­tion with access to Active Directory profiles, or have another identity service deployed. In my experience these can have a range of lim­i­ta­tions including poor data quality, and a heavy­weight pro­gram­ming model.

It would be nice to be able to implement something along the lines of Facebook Login. ASP.NET MVC 4.0 provides great support for social au­then­ti­ca­tion providers, but out of the box it doesn’t provide support for any enterprise social networks. These building blocks are, however, an excellent foundation for im­ple­ment­ing support for a Yammer provider.

Yammer is an enterprise social network (ESN) and at the core of the func­tion­al­i­ty is a user profile for each user within your or­ga­ni­za­tion. These profiles are controlled by users, and often have content that is more up-to-date than internal di­rec­to­ries. In many cases customers are also using Directory Sync to update profile fields. I took some time to implement an OAuth 2.0 client which is compatible with Yammer, and I'm sharing the details below. This can be used in ASP.NET MVC sites, but it is something that you could modify to work with other types of .NET ap­pli­ca­tions. There are however better choices for Windows Phone where an SDK is available.

Im­ple­ment­ing the client

As ASP.NET MVC builds on func­tion­al­i­ty from Dot­Ne­tOpe­nAuth the focus is on extending OAu­th2­Client as Yam­mer­Client. The complete im­ple­men­ta­tion is available online, but the methods you need to implement are:

  1. Get­Ser­viceL­ogin­Url() which is re­spon­si­ble for preparing the URL to redirect the user so that they can authorize your ap­­pli­­ca­­tion.
  2. Query­Ac­cessTo­ken() which executes a callback to Yammer in exchange for an OAuth access token.
  3. Ge­­tUser­­Da­­ta() which is re­spon­si­ble for querying profile data.

Something worth noting is that if you want to be able to make Yammer API calls, or silently check for profile updates, then you may need to modify Ge­tUser­Da­ta() to persist the token.

Using the client

Using the client in a new ASP.NET MVC Internet Ap­pli­ca­tion project is straight­for­ward. Before going any further there are some steps you need to take to register an ap­pli­ca­tion on the Yammer site. These steps can be completed through the registered ap­pli­ca­tions page, and detailed in­struc­tions are provided on the developer site. It is very important that you set a Redirect URI for your Yammer ap­pli­ca­tion. The format will be along the lines of http://localhost:31074/ for your de­vel­op­ment site in Visual Studio (adjust the port!), but you'll need to change it to something like https://www.myapp.com/authorize for production.

Back in Visual Studio you simply need to in­stan­ti­ate an instance of the Yam­mer­Client class, and register it in AuthConfig.cs:

public static void RegisterAuth()
{
    const string appId = "Your Application ID";
    const string appSecret = "Your Application Secret";
    var client = new YammerClient(appId, appSecret);
    OAuthWebSecurity.RegisterClient(client, "Yammer", null);
}

When your ap­pli­ca­tion is launched it'll offer the ability to sign in with Yammer and any other OAuth au­then­ti­ca­tion clients that you have registered. It really is very slick!

A good next step is to modify your con­trollers and views to take advantage of the profile in­for­ma­tion beyond basic profile fields. That seems like good fodder for a future blog post.

Tagged with yammer, oauth, rest, authentication and security.

Debugging problems with IE Security Zones

Internet Explorer has quite a complex security model compared to other browsers. One unique feature is the infamous Security Zone. Zones apply different policies to code based on the URL. By default, you have the following zones: Internet, Local Intranet, Trusted Sites, Restricted Sites, and My Computer.

IE Zones Dialog screenshot.

Each of these zones has a slightly different con­fig­u­ra­tion depending on the intended usage. For example, the Internet zone is designed to handle untrusted code from the internet. The settings are locked down tightly, and recent versions of IE run this code in a sandbox with Protected Mode.

Compare this to the Intranet zone which has a more relaxed con­fig­u­ra­tion. If a URL is included in this zone it is considered to be trusted to a greater degree than one in the Internet zone. IE will even respond dif­fer­ent­ly to au­then­ti­ca­tion requests for sites in the Intranet zone to support Windows Au­then­ti­ca­tion (see IWA, NTLM, Kerberos, and SPEGNO.)

Everything is fine and dandy when your ap­pli­ca­tion has code that only loads from URLs belonging to a single zone. However, things will start to go pear-shaped when you have code loading from different zones. The exact behaviour will depend on your ap­pli­ca­tion, but you'll often see in­con­sis­tent behaviour between en­vi­ron­ments. The ex­pla­na­tion for this is often the ap­pli­ca­tion of group policy resulting in different con­n­fig­u­ra­tions across machines.

So how do you go about debugging these issues? My approach is to start with the following:

  1. Make sure the problem only happens in IE. Doing this will save you a lot of pain as debugging with the Chrome developer tools is often a more pleasant experience than using the IE tools.
  2. Identify all of the domains hosting your code. Understand what zones contain your host page, and which ones contain other scripts or code that you are pulling in.
  3. Tem­porar­i­ly move all of the code into a single zone. If you move all of your code into a single zone for testing you can confirm whether Protected Mode issues are at the heart of your problem. You may need to tweak some IE zone settings to get the features you need, but it's a good start.
  4. Disable com­pat­i­bil­i­ty view. Sites in the Intranet zone use this feature by default, and it can cause problems. Tem­porar­i­ly turn it completely off for the Intranet Zone so that that things are consistent across zones.
  5. Use IE Zone Analyzer. This tool allows you to review the con­fig­u­ra­tion of zones in great detail, and help with bugs that only appear in certain en­vi­ron­ments. It is available for free from Microsoft.

IE Zone Analyzer screenshot.

At this point you'll be in a better position to debug specific code in IE, but how do you remediate the problem? Well you have to make a change somewhere. It is common for admins to add wildcards like *.domain.com to the Intranet zone. Naturally this will not dis­crim­i­nate between Intranet sites, and cause a lot of problems if you have modern code that doesn't run well under Com­pat­i­bil­i­ty View. Try to educate your admins on the ap­pro­pri­ate con­fig­u­ra­tion so that your en­vi­ron­ment will be more secure, and you'll also spend less time debugging!

Tagged with internet-explorer, javascript and debugging.

Speeding up archive operations on OS X and Linux

I work with a lot of virtual machine images and other big data sets that needed to be archived, or moved around. If I run a command like tar -cjf archive.tar.bz2 directory it will churn away on a single core.

Given that all my machines have a lot of cores, it would be better if the tar command made use of all available cores. Thankfully someone created a tool called pigz (pronounced "pig-zee") that will allow the use of these CPU cores.

There are 2 parts to the setup for pigz: get the utility, and force tar to use it. On my Mac I grabbed pigz from brew:

brew install pigz

Then I added an alias so that tar uses this by default:

alias tar='tar --use-compress-program=pigz'

Remember that you might not want to use an alias if your profile travels with you to en­vi­ron­ments where the use of all cores could create problems.

« Older Posts