Search code examples
c#azure.net-coreasp.net-identityazure-service-fabric

Identity Framework GenerateUserToken validation issue


I have a Service Fabric project in which I have a stateless WebAPI project. When a new user is created, we generate a token. I have used Identity framework's UserManager.GenerateUserToken as follows:

var inviteUserToken = await userManager.GenerateUserTokenAsync(user, "PasswordTokenProvider", "Password");

We send this token in mail, and it will be resent to the server for verifcation. The vertification method is as follows:

  var verifyToken = await userManager.VerifyUserTokenAsync(user, "PasswordTokenProvider", "Password", inviteUserToken);

Now I have two environments: one with a 1-node cluster and another with a 3-node cluster. Everything is working perfectly in the 1-node cluster. But in the 3-node cluster, the verify token behaviour is very random. It sometimes works and sometimes it fails to verify.

Note: Both environments are exactly same, except for the number of nodes.


Solution

  • The problem you are facing is because the encryption keys used to generate the token are different on each node(machine). i.e: when you generate a token on node1 it uses key 123 but when you decode on node2 it uses the key 345. Every node in the cluster must use the same key to work properly.

    In the past, these where defined by machine.config auto generated keys, on dotnet core it is based on data protection auto generated keys.

    You have a few options:

    • store these keys in a shared network folder
    • store these keys in a blob storage
    • copy them on every node where the application runs

    then, you will register it with a code similar to this:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDataProtection()
            .PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\directory\"))
    }
    

    Make sure to protect access to these keys to avoid undesired access. You might also decide to encrypt these keys to avoid being used in case they get compromised.

    You may also need to configure the TokenOptions to use the new data protection provider, take a look at this link for more details.