Getting Back on the Horse

I grew up on a farm and ranch driving tractors mostly but riding horses to herd cows and to play as often as was possible. It was an idyllic way to grow up. I was more of a farmer than I was a cowboy, but I loved old western movies, especially John Wayne, and idolized the American Cowboy and the cowboy way of life.

This painting by a family friend named Lynn E. Mecham reminds me of all that I love about cowboys.

cowboys_thumb2

I encourage you to visit his Facebook page for his gallery. He does amazing work.

As a young boy one of my favorite pastimes was to saddle up the horse and join a few of my friends in a game of tag on horseback in the cedar and sage brush hills above the small farm on which I grew up. Of course we knew nothing really about the politics surrounding the treatment of Native Americans. For us it was just a game.

On one of these occasions, I was riding my brother's mare Toots, a beautiful buckskin that looked very much like this.

toots_thumb1

I was an Indian. One of my friends was selected to be the Cowboy, the guy who had to catch one of us. I had Toots running through the sage brush and planned to ditch the Cowboy in a barrel turn around a large cedar tree coming up on my left. I pulled left on the reins at just the right moment and she juked left around the tree.

Suddenly I was laying on the sand on my back, pain throbbing in my chest and, for a moment, I was unable to breathe. The tree had a large branch sticking out right at my chest height from the saddle. I was not hurt badly. I found Toots looking back at me as if to say, "What happened to you?" I got back on after a few minutes and we continued playing.

I learned a valuable lesson that day. Even when you're in a hurry, be cautious when rushing into a place you've never before been. You might get knocked off your horse, but you'll probably survive.

Fast forward a few decades to this year. After surviving a health crisis in India, I'm now dressing like a cowboy to remind myself to work hard and take better care of myself. And I'm still "playing" with Indians. But in this case real Indians.

I work with two teams of wonderful developers and testers in the New Delhi area. I have spent a little more than a year working with them. I was enjoying myself so much that I forgot the lesson of my youth and traveled in July to work and have fun with my Indian colleagues.

funday2_thumb1

I nearly died in India after that fun day. I got knocked off my horse. It took several weeks to get back up, but I did. And I may come off my horse again, but like my dad always taught me, I will get back on. I hope you do too.

5 Keys to JSON Web Tokens and ASP.NET Core 2

I know JSON Web Tokens (JWT) have been around for a while, but I still run into many developers who do not know much or anything about them. You can read much more in the JWT Handbook and at one of my favorite online tool sites for using JWT at jwt.io.

Here are the 5 things I think you should know about JWT:

#1. OpenID

If you're not already using OpenID, a standard for single sign-on and identity provision, you should be looking into it. There are many sites where you can learn more about OpenID. The connect2id.com OpenID overview is a good place to start. And if you're using ASP.NET Core 2 and IdentityServer4, you definitely want to know more about JWT and OpenID.

#2. Security Concerns

You can encrypt your JWT tokens but most do not. You can include whatever you want in terms of claims in the token. Here's an example of a token trimmed down for length to simply demonstrate what an encoded token may look like. Note the "." dividers.

eyJ0eXAiOF1RSJ9.eyJpc3MiOiJNlcyIsImV4cb3JkIl19.AsYr7vaxFqCztZ_wph_

Here is what that token may look like when decoded from the Base 64 string:

Header

{
  "typ": "JWT",
  "alg": "RS256",
  "x5t": "a3rMUgMFv9tPclLa6yF3zAkfquE",
  "kid": "a3rMUgMFv9tPclLa6yF3zAkfquE"
}

Payload Data

{
  "iss": "https://identity.yourdomain.com/identity",
  "aud": "https://identity.yourdomain.com/identity/resources",
  "exp": 1512842905,
  "nbf": 1512839305,
  "client_id": "apiclient",
  "scope": "openid",
  "sub": "108434458",
  "auth_time": 1512839305,
  "idp": "youridpid",
  "amr": [
    "password"
  ]
}

So what do you need to be worried about with respect to security? Simply this. Make sure whatever you put into your JWT tokens do not reveal secrets or sensitive data that you do not want discovered. Yes, of course, the JWT is signed. The third part of the token is a hash created by the identity server and must be validated on the server side accepting the token when you use it in the Authorization header as a Bearer token.

This means the server side has to have the key used to validate. But on the client side, for unencrypted JWT tokens, the data can be useful. Just don't make it useful to the bad actor. And when you decide to add claims to your JWT from your identity server implementation, be sure you are comfortable with that data being out in the wild.

#3 Authorization Most Common Use

The most common use of a JWT is as a bearer token in the Authorization header as I've just mentioned.

Authorization: Bearer [token]

Here's the flow.

  1. Browser (or API client) sends POST to identity endpoint with username and password.
  2. Identity server authenticates and creates JWT signed with secret key or certificate.
  3. Browser (or API client) receives the JWT token.
  4. Browser (or API client) makes request to the app server with Authorization header with "Bearer [token]" in request.
  5. App server validates the JWT token and authorizes and executes the request or denies it.
  6. Browser (or API client) receives response from the application server.

#4 Getting the "sub" Claim Back from Microsoft's Mapping

Before you spend a lot of time in ASP.NET Core 2 trying to get access to the "sub" (subject) claim in the controller's User (cast as ClaimsPrincipal), just know that it's not your fault. It's Microsoft's. They map claims and are not 100% compliant with the OpenID standard in that the "sub" claim disappears. Here's how you get it back:

public void ConfigureServices(IServiceCollection services)
{
  //config services like logging, Mvc, etc.
  
  JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); 
  
  //config services.AddAuthentication and AddAuthorization
}

By removing the "sub" claim from their claim type map, it will reappear in your ClaimsPrincipal like this dummy code written simply to show how to grab the "sub" claim now that it's back.

[HttpGet("{id}"), Authorize("openid")]
public string Get(int id)
{
  var user = User as ClaimsPrincipal;
  var memId = user.Claims
      .Where(x => x.Type == "sub")
      .Select(x => x.Value).FirstOrDefault();
  return memId;
}

Try that without removing it from the type map and you'll get a big fat null.

#5 JWT Tokens Can and Should Expire

If you are using JWT and OpenID, you should make sure that your identity server sets an expiration on the token. And if your authentication request provides your with a refresh token, you should learn how in the client to refresh (call the identity server with the refresh token) your access JWT token. See auth0's details on using refresh tokens.

A refresh token is especially useful for keeping a user logged in without asking her or him to enter a username and password again. And it is a great way to avoid storing credentials locally. Yeah, don't do that.

Conclusion

If you're not using JWT or have not yet become comfortable with tokens, you owe it to yourself to do a little reading, even if you're not a coder. But if you're a coder, you definitely need to grok JWT.

I'm Glad I Died in India

Last summer I died in India, figuratively if not quite literally. And I'm glad..

I won't bore you with the details. Here's the nutshell. My wife and I traveled to New Delhi for work and fun to be followed a 9 day 30th anniversary celebration in Ireland on our way home. A health crisis intervened. I nearly died twice. I spent ten days in ICU under the care of the very capable physicians and other professionals at Max Hospital in New Delhi.

I lost more than just 25 pounds and 15 more since then. The person I was died there in that hospital bed. I returned with a renewed determination to waste no more time on the irrelevant and the unnecessary. I left behind a man of too much wasted time and too many unproductive habits. I came home with a new lease on life, and I wasn't going to waste it.

newmeFirst and foremost, thanks go to my dear wife without whom I certainly would have died. Secondly great thanks go to all my Indian coworkers, several of whom participated in my rescue from certain death, and the management team back home who made sure that our every need was very well met.

This photo was taken of me a few weeks after our return to Utah. It's how I dressed as a young kid growing up on a farm and ranch. It's how my dad still dresses. It's my way of reminding myself to be more like him and focus on the important things in life while eliminating things that don't matter and just waste time.

Because my health crisis was in precipitated by my poor personal health habits of the past and a nasty intestinal infection contracted in my first few days in country, I've spent a good deal of time learning how to take better care of myself with a sensible diet and exercise, making good on a commitment to create a lifelong habit and avoid repeating my nightmare in New Delhi.

I stopped watching television. I stopped paying much attention to politics and I never waste time commenting on that topic. I spend more time with my family. I rise early and retire early. I spend time in personal study and devotions every day. And I strive to treat others, especially those with whom I work, as I would wish to be treated, with kindness and patience.

It has been a transformative experience. I grew so much closer to the great people on my teams and all those who took care of my wife while I fought off death in the hospital. I know I'm not the only one to have gone through something like this. There are many who emerge from such a health crisis changed, better, more alive than ever before. I am deeply grateful for the opportunity to see from this perspective, though I recommend you take my word for it. And it sure beats looking up from six feet under.

...

P.S. It's been nearly a year since I posted my last blog post. You can expect to see me posts more often. Most of my posts in this blog have been about software development. I'm thinking you'll see a mix of technology and personal posts in the future. I hope you don't mind.

Announcing MessageWire

During the holidays I began playing with a port of the Zero Knowledge code in ServiceWire but using NetMQ, the .NET native port of ZeroMQ. I’ve named this fun little project MessageWire and I’m happy to announce the first release and show off this new logo.

MessageWireLogo

MessageWire is a Zero Knowledge authentication and encryption wrapper for a NetMQ Dealer socket (client) Router socket (server) combination.

Get the code here. Get the NuGet package here. I’ll be blogging more about it as the code evolves. It’s early days so use at your own risk.

Serverless–AWS Lamba vs Azure Functions

Who will win the Serverless Wars? Azure Functions is the latecomer but has much to like. AWS is the original trailblazer but appears to be slacking off in terms of innovation. I’m not sure there needs to be a winner. There will certainly be those who prefer AWS and those who prefer Azure for a variety of reasons. In this post, I’ll attempt to catalog the differences I’ve been able to find.

lamdavsfunctions

Incidentally, if you have not been introduced to the topic of Serverless Architectures, I suggest Martin Fowler. I have watched with fascination Martin Fowler’s posts on Serverless architectures. There are many other sources you will find through the magic of Google, but give Martin a read before you resort to the others.

Warning! The comparison below is by no means comprehensive and should not be considered conclusive. These are my initial impressions based on research only.

Serverless Features AWS Lamda Azure Functions
Supported Languages Node.js, Python, Java Node.js, Python, PHP, F#, C#
Web Dashboard adequate excellent (VS Online included)
Physical Logical Container single container deployed from zip (Linux) App Service contains multiple functions (Windows)
Continuous Deployment CLI (some 3rd party tools) GitHub, BitBucket, Dropbox, VS Team Services, VS Online editor
Source Code closed open
HTTP endpoint per function/lamda requires API Gateway configuration (greater flexibility at cost of simplicity) automatic (one per)
Authentication unknown Facebook, Google, Twitter, Microsoft
Cross-Origin Resource Sharing (CORS) unknown supported
Maximum execution time per request 5 minutes unlimited (potential unlimited cost)
Persistence of instance and environment variable no yes

 

If you don’t speak the language, you won’t be much good at communicating, so for me the choice is easy. Azure Functions supports C#, my language of choice. All the rest is just gravy. I’m sure your choice and mileage will vary.

Also check out Google’s Cloud Functions as well. Though I doubt they will succeed like Azure and AWS, anything is possible.

ServiceWire 5.0 with .NET Core Support Released

I’m happy to announce the release of ServiceWire 5.0 with .NET Core support published to NuGet today. The final trick was preparation of the NuGet package which was greatly helped by Armen Shimoon of dotnetliberty on using project.json for NuGet package metadata. The post was written in January 2016, so it was a bit out of date. The project.json file ended up like this:

{
  "name": "ServiceWire",
  "title": "ServiceWire",
  "authors": [ "Tyler Jensen" ],
  "description": "ServiceWire is a very fast...",
  "projectUrl": "https://github.com/tylerjensen/ServiceWire",
  "packOptions": {
    "iconUrl": "http://www.tsjensen.com/blog/image.axd?picture=2014/11/swlogo_sm.png",
    "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0",
    "copyright": "Tyler Jensen 2013-2016",
    "owners": [ "Tyler Jense" ],
    "summary": "ServiceWire is a fast and easy RPC library...",
    "releaseNotes": "BREAKING CHANGES: Ported to .NET Core netstandard1.6...",
    "tags": [ "WCF", "Services", "Host", "Client", "..." ]
  },
  "version": "5.0.0-*",

  "dependencies": {
    "NETStandard.Library": "1.6.0",
    "Newtonsoft.Json": "9.0.1"
  },

  "frameworks": {
    "netstandard1.6": {
      "imports": "dnxcore50",
      "dependencies": {
        "System.Reflection.Emit": "4.0.1",
        "System.Threading.Thread": "4.0.0"
      }
    },
    "net45": {
      "dependencies": {
        "System.Reflection.Emit": "4.0.1"
      },
      "frameworkAssemblies": {
        "System.Management": "4.0.0.0"
      }
    },
    "net461": {
      "dependencies": {
        "System.IO.Pipes": "4.0.0",
        "System.Reflection.Emit": "4.0.1",
        "System.Threading.Thread": "4.0.0"
      },
      "frameworkAssemblies": {
        "System.Management": "4.0.0.0"
      }
    },
    "net40": {
      "frameworkAssemblies": {
        "System.Management": "4.0.0.0"
      }
    },
    "net35": {
      "dependencies": {
        "TaskParallelLibrary": "1.0.2856"
      }
    }
  }
}

Then packaging up the NuGet package was easy with this command:

dotnet pack ServiceWire.Core -c Release -o D:\NugetPackages

Then just push it to NuGet. Simple as that.

And this concludes the porting of ServiceWire to .NET Core. But there’s more. There is always more. Some features were disabled in the NET Stardard 1.6 build and so a bit of utility work is still required. And there is some fun work ahead to make the library even easier to use. And then there is some performance work that out to be done along with some new unit tests using xUnit.

If you enjoy using ServiceWire, I’d love to hear from you. And I would love to have more pull requests from those who find bugs or ways to improve it.

.NET Core on Linux with ServiceWire

After a BIOS update, I was able to get Hyper-V working on my Windows 10 Pro machine and spun up an Ubuntu 16.04 instance. Once it was up and running I just followed the .NET Core Linux install instructions. No other changes to the VM.

Using the Portable Application instructions on the new docs.microsoft.com site for .NET Core, I executed the following commands to prep the CoreTestClient1 project for deployment to the Linux VM with my command prompt in the root directory of the project.

dotnet restore

and then

dotnet publish -f netcoreapp1.0 -c release

From there it was just a matter of copying the files in the \bin\Release\netcoreapp1.0\publish folder to a new folder called test1 on the Linux VM using an smb local file share.

After spinning up a debug instance of CoreTestHost on my Windows machine in Visual Studio, I tried to run CoreTestClient1 in the Ubuntu VM first without the extension. Oops. Then got it right and then tried it again just our of sheer delight.

linuxdotnet

The results are not particularly impressive as I was running on a VM with a single core, but the fact that it ran and without a hitch was enough to make me very happy. With a single day of porting to .NET Core and one more to remember how to install and use Linux on a Windows Hyper-V virtual machine and not a single bug that had to be fixed, I was able to complete the following essential requirements using only .NET Core, C# and ServiceWire

Requirements

  • Write an interface in a class library project called Common.
  • Write an implementation for that interface in class library project called Impl.
  • Write a console app that will host the implementation in a project called Host.
    • This project may reference Common and Impl.
    • Using ServiceWire allow remote calls to the implementation of the interface.
  • Write a console app called project Client.
    • This project may only reference Common.
    • Using ServiceWire, connect to Host and call the methods on the interface.
    • Write the results to the console.
  • Write all of this code on a single Windows machine with Visual Studio.
  • Run the Host project on the Windows machine.
  • Deploy the Client project to a Linux machine and run it from the Linux shell.
  • No tricks. You may not use Mono.

For examples of the code that you might find in the Host and Client, have a look at my previous post.

What’s Next?

Next I will be working on producing a NuGet package for ServiceWire 5.0.

Final Confession
It wasn’t quite all that smooth as I had not touched Linux or Hyper-V in years, so there were a few bumps, including a hosed up virtual network adapter that left my first Ubuntu install crippled. I also tried building and deploying a self contained app which required changes to the project.json file, but I gave it up as folly since I had already installed .NET Core on the Linux VM. And after deploying the portable app the first time, I was trying to run the app with “dotnet run” rather than “dotnet {assemblyFileName}” and of course that did not work. All told, I spent about 6 to 8 hours on all of this but that was broken up by multiple distractions so it required two calendar days. Now that the learning curve has been climbed, the next time out of the box should be much easier. And I hope this post will help you. I know it will serve well as a bookmark for me the next time I climb this curve. And that should be soon.

ServiceWire and .NET Core Integration Tests

I’m very happy with the quick and dirty .NET Core integration test code I’ve just committed to GitHub for ServiceWire. The only changes to existing integration test code were these:

Removal of Named Pipes from the test since .NET Core does not support Named Pipes (so far as I can learn) as Named Pipes is a Windows only thing (again, so far as I have learned).

Modified code to get IP address and port from command line args rather than configuration along with some defaults.

So here’s the primary host host code. Note how easy it is to host implementations for multiple interfaces.

class Program
{
   static void Main(string[] args)
   {
      var logger = new Logger(logLevel: LogLevel.Debug);
      var stats = new Stats();

      var addr = new[] { "127.0.0.1", "8098" }; //defaults
      if (null != args && args.Length > 0)
      {
         var parts = args[0].Split(':');
         if (parts.Length > 1) addr[1] = parts[1];
         addr[0] = parts[0];
      }

      var ip = addr[0];
      var port = Convert.ToInt32(addr[1]);
      var ipEndpoint = new IPEndPoint(IPAddress.Any, port);

      var useCompression = false;
      var compressionThreshold = 131072; //128KB

      var tester = new NetTester();
      var mytester = new MyTester();

      var tcphost = new TcpHost(ipEndpoint, logger, stats);
      tcphost.UseCompression = useCompression;
      tcphost.CompressionThreshold = compressionThreshold;
      tcphost.AddService<INetTester>(tester);
      tcphost.AddService<IMyTester>(mytester);

      var valTypes = new ValTypes();
      tcphost.AddService<IValTypes>(valTypes);

      tcphost.Open();

      Console.WriteLine("Press Enter to stop the dual host test.");
      Console.ReadLine();

      tcphost.Close();

      Console.WriteLine("Press Enter to quit.");
      Console.ReadLine();
   }
}

And here’s the client code.

class Program
{
   private static void Main(string[] args)
   {
      var addr = new[] { "127.0.0.1", "8098" }; //defaults
      if (null != args && args.Length > 0)
      {
         var parts = args[0].Split(':');
         if (parts.Length > 1) addr[1] = parts[1];
         addr[0] = parts[0];
      }

      var ip = addr[0];
      var port = Convert.ToInt32(addr[1]);
      var ipEndpoint = new IPEndPoint(IPAddress.Parse(ip), port);
      for (int i = 0; i < 1; i++) RunTest(ipEndpoint, ip);

      Console.ReadLine();
   }

   private static void RunTest(IPEndPoint ipEndpoint, string ip)
   {
      using (var client = new TcpClient<IValTypes>(ipEndpoint))
      {
         decimal abc = client.Proxy.GetDecimal(4.5m);
         bool result = client.Proxy.OutDecimal(abc);
      }

      using (var client = new NetTcpTesterProxy(ipEndpoint))
      {
         var id = client.GetId("test1", 3.314, 42, DateTime.Now);
         long q = 3;
         var response = client.Get(id, "mirror", 4.123, out q);
         var list = client.GetItems(id);
      }
      using (var client = new NetTcpMyTesterProxy(ipEndpoint))
      {
         var id = client.GetId("test1", 3.314, 42);
         int q2 = 4;
         var response = client.Get(id, "mirror", 4.123, out q2);
         var list = client.GetItems(id, new int[] { 3, 6, 9 });
      }

      var sw = Stopwatch.StartNew();
      var from = 0;
      var to = 400;
      Parallel.For(from, to, index =>
      {
         using (var client = new NetTcpTesterProxy(ipEndpoint))
         {
            for (int i = 0; i < 10; i++)
            {
               var id = client.GetId("test1", 3.314, 42, DateTime.Now);
               long q = 2;
               var response = client.Get(id, "mirror", 4.123, out q);
               var list = client.GetItems(id);
            }
         }

         using (var client = new NetTcpMyTesterProxy(ipEndpoint))
         {
            for (int i = 0; i < 10; i++)
            {
               var id = client.GetId("test1", 3.314, 42);
               int q2 = 6;
               var response = client.Get(id, "mirror", 4.123, out q2);
               var list = client.GetItems(id, new int[] { 3, 6, 9 });
            }
         }
      });
      sw.Stop();
      var msperop = sw.ElapsedMilliseconds / 24000.0;
      Console.WriteLine("tcp: {0}, {1}", sw.ElapsedMilliseconds, msperop);
   }
}

It’s quite simple, but I’m going to be working on both host and client code to make it easier to code up both of them with some convention assumptions that will also not break existing host and client code. After that, I’ll publish a new NuGet package with a major version rev to 5.0.