4

I have a .NET Core application with Angular2 UI running in a Service Fabric Cluster that I secured using OpenIddict. I followed this example: https://github.com/openiddict/openiddict-samples/tree/master/samples/RefreshFlow

It works great when I only have one instance of the stateless .NET Core application. When I increase the instance count to two, the authentication fails and I get a bunch of 401 errors. It seems that the token I receive is only good for that particular instance and is rejected on the other instance. I think I understand why this is happening, but I’m not sure how to address it.

Any help would be greatly appreciated.

Kévin Chalet
  • 39,509
  • 7
  • 121
  • 131
Per
  • 491
  • 6
  • 19

2 Answers2

3

OpenIddict relies on the ASP.NET Core Data Protection stack to generate and protect its authorization codes, refresh tokens and access tokens (unless you explicitly opt for JWT as the access token format).

To ensure these tokens can be read across instances, you must configure ASP.NET Core Data Protection to share the same key ring. I recommend reading the related documentation on Microsoft's website if you need more information about this procedure.

Kévin Chalet
  • 39,509
  • 7
  • 121
  • 131
  • I'd assume this would be relevant to any system that needs to decrypt data on separate instances? Also, never heard of openiddict before, currently using idsrv4, shall have to have a look. Great work :) – Mardoxx Apr 08 '17 at 09:42
  • 1
    @Mardoxx yes, it applies to everything using ASP.NET Core Data Protection, which includes authentication cookies or data you encrypt yourself with `IDataProtector`. – Kévin Chalet Apr 08 '17 at 09:44
  • I'm marking this as the answer since it pointed me in the right direction. I have added post below with some instructions that pertain to Service Fabric cluster. – Per Apr 24 '17 at 18:28
1

I solved this by looking at this: https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-storage-providers#azure-and-redis

Here are the basic steps I took:

  1. Create a blob storage account to store the shared keys.

  2. Add the following code to your Startup.cs:

var storageAccount = CloudStorageAccount.Parse("blob storage connection string");

//Create the blob client object.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

//Get a reference to a container to use for the sample code, and create it if it does not exist.
CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
container.CreateIfNotExists();

services.AddDataProtection()
    .SetApplicationName("MyApplication")
    .PersistKeysToAzureBlobStorage(container, "myblobname");

That was it.

Per
  • 491
  • 6
  • 19