0

Is claims-based authorisation supported in Service Fabric stateless services?

Let's say that I have a web api that receives a JWT in the header. Can I pass the JWT or claims within to a Service fabric stateless service so that it can do some checking on the claims before performing sensitive operations?

I can see that we can pass in claims to a service by using ClaimsCredentials:

var serviceProxyFactory = new ServiceProxyFactory(
    (callbackClient) => new FabricTransportServiceRemotingClientFactory(
        new FabricTransportSettings
        {
            SecurityCredentials = new ClaimsCredentials
            {
                LocalClaims = "[JWT HERE? or just Claims JSON?]"
            }
        }));

IMyService service = serviceProxyFactory.CreateServiceProxy<IMyService>(new Uri("fabric:/MyThing/MyService"));

https://msdn.microsoft.com/en-us/library/azure/system.fabric.claimscredentials.localclaims.aspx says that LocalClaims is "the string representation of claims token acquired from STS (security token service)."

Also:

  • Is ClaimsCredentials actually the base64 encoded JWT, or just a JSON payload of claim key:value properties?

  • Is there any specific configuration or code needed to be done in the stateless service?

  • How do you get access to the claims from the stateless service?

At the moment, when I call the service, I get the following error, no matter what value I set LocalClaims to:

System.Fabric.FabricCannotConnectException: Error in Connection during ServiceCommunication 
 ---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80071C4C\r\n   
 at Microsoft.ServiceFabric.Services.Communication.FabricTransport.Common.NativeServiceCommunication.IFabricServiceCommunicationClient2.EndRequest(IFabricAsyncOperationContext context)\r\n   
 at Microsoft.ServiceFabric.Services.Communication.FabricTransport.Client.NativeServiceCommunicationClient.EndRequest(IFabricAsyncOperationContext context)\r\n   at System.Fabric.Interop.AsyncCallOutAdapter2`1.Finish(IFabricAsyncOperationContext context, Boolean expectedCompletedSynchronously)\r\n   --- End of inner exception stack trace ---\r\n   
 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   
 at Microsoft.ServiceFabric.Services.Communication.FabricTransport.Client.NativeServiceCommunicationClient.<RequestResponseAsync>d__8.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at Microsoft.ServiceFabric.Services.Communication.Client.ServicePartitionClient`1.<InvokeWithRetryAsync>d__7`1.MoveNext()

Thanks!

Adam
  • 41
  • 3

1 Answers1

2

I don't think the ClaimsCredentials class is intended to carry a JWT token but rather a security token generated by Service Fabric itself, based of some certificate. If you inspect the class ClaimsCredentials you see that it is closely tied to a native class that carries claims info. Digging deeper into that reveals a struct that is used to pass information:

[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct FABRIC_CLAIMS_CREDENTIALS
{
  public uint ServerCommonNameCount;
  public IntPtr ServerCommonNames;
  public uint IssuerThumbprintCount;
  public IntPtr IssuerThumbprints;
  public IntPtr LocalClaims;
  public NativeTypes.FABRIC_PROTECTION_LEVEL ProtectionLevel;
  public IntPtr Reserved;
}

[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct FABRIC_CLAIMS_CREDENTIALS_EX1
{
  public uint ServerThumbprintCount;
  public IntPtr ServerThumbprints;
  public IntPtr Reserved;
}

There is a lot about this class that screams internal and nothing that indicates any relation to, or understanding of, JWTs.

If you want to add some form of security in your HTTP endpoints then you should be able to use the System.IdentityModel.Tokens.JwtSecurityTokenHandler, have a look at this SO answer to get started: Decoding and verifying JWT token using System.IdentityModel.Tokens.Jwt.

If you want to add JWT-based security to your Fabric Transport endpoints, then you probably need to add the JWT as a custom header in your client using ServiceRemotingMessageHeaders and then parse and validate that header on the listener. Using the supplied and documented security model for service remoting with X509 certificates might be a better choice for this transport thought.

Ronald Wildenberg
  • 31,634
  • 14
  • 90
  • 133
yoape
  • 3,285
  • 1
  • 14
  • 27