Currently, I have Identity Server 4 running with one instance in a Standalone Service Fabric Cluster with 1 instance of Ocelot in the same cluster and 5 instances of a service that only returns an array of values but in this last service I need to read or get some Claims of the users that were authenticated in Ocelot.
How to send the claims from Ocelot to that internal service?
Greetings
@licjapodaca I think you have two options, Ocelot will forward the authorization header to your services so you can parse the token again and get the claim value or you can use the claims tranformation feauture, the docs are here
Thanks @TomPallister for your help, finally I have the complete solution to generate, get, transform and send the claims with Ocelot to the internal Service Fabric (Microservices) as follow:
public static IEnumerable<ApiResource> ApiResources()
{
return new List<ApiResource>
{
new ApiResource("socialnetwork", "Social Network")
{
// Define the claims that will use the Resource and generate in the Token
UserClaims = new List<string> { "City", "State" }
}
};
}
public static IEnumerable<Client> Clients()
{
return new[]
{
new Client
{
ClientId = "socialnetworkclient",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedScopes = { "socialnetwork" },
AccessTokenType = AccessTokenType.Jwt,
// Specify that I want to include the claims in the same Token
AlwaysSendClientClaims = true
}
};
}
public static IEnumerable<TestUser> Users()
{
return new[]
{
new TestUser
{
SubjectId = "1",
Username = "[email protected]",
Password = "*******",
Claims = new List<Claim>
{
new Claim("City", "Mexicali"),
new Claim("State", "Baja California")
}
}
};
}
http://+/connect/token I confirm that the claims was returned in the Token, decoded with the help of https://jwt.io website as follow:
configuration.json Ocelot file with the specification as the docs says here with the following json code:{
"ReRoutes": [
{
"DownstreamPathTemplate": "/{route}",
"UpstreamPathTemplate": "/servicea/{route}",
"UpstreamHttpMethod": [ "Get", "Post", "Put", "Patch", "Delete", "Options" ],
"DownstreamScheme": "http",
"ServiceName": "ServiceFabricApplication/ServiceA",
"UseServiceDiscovery": true,
"AuthenticationOptions": {
"AuthenticationProviderKey": "TestKey",
"AllowedScopes": []
},
// Here it is the instruction for the conversion of Claims
// to request Headers
"AddHeadersToRequest": {
"claims_City": "Claims[City] > value > |",
"claims_State": "Claims[State] > value > |"
}
},
{
"DownstreamPathTemplate": "/{route}",
"UpstreamPathTemplate": "/serviceoauth/{route}",
"UpstreamHttpMethod": [ "Get", "Post", "Put", "Patch", "Delete", "Options" ],
"DownstreamScheme": "http",
"ServiceName": "ServiceFabricApplication/ServiceOAuth",
"UseServiceDiscovery": true
}
],
"GlobalConfiguration": {
"RequestIdKey": "OcRequestId",
"AdministrationPath": "/administration",
"ServiceDiscoveryProvider": {
"Host": "localhost",
"Port": 19081,
"Type": "ServiceFabric"
}
}
}

That's all ... thanks again @TomPallister
Here it is the complete source code sample that I want to share for everyone GitHub Repository
@licjapodaca awesome :) thanks!!
@licjapodaca Great, man! You saved the day!
You're welcome :)
@licjapodaca I'm trying to forward some claims value to route parameter, but in the destination api service these values has the placeholder name instead of the claim value.
My ocelot.json
"ReRoutes": [
{
"DownstreamPathTemplate": "/api/test/{company}/{customerCode}",
"ChangeDownstreamPathTemplate": {
"company": "Claims[company] > value > |",
"customerCode": "Claims[customerCode] > value > |"
},
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 60700
}],
"UpstreamHeaderTransform": {
"user-host-ip": "{RemoteIpAddress}",
"proxy-host": "{BaseUrl}"
},
"UpstreamPathTemplate": "/test/template",
"UpstreamHttpMethod": [ "Get", "Post" ],
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": []
},
}
]
In the service api action "Get"

We have custom claims with custom schema; what's wrong with my configuration?
Thank you!
@Fabman08 Hi there, first of all, try to use the same Business Logic I used in this issue, check my configuration.json file that correspond to your ocelot.json file, and use the same properties to transform your Claims into Request Headers, be based on this resource link (Claims Transformation), and in the API service the Claims that comes in the request headers, they arrive as so, as request headers and NOT as parameters in the action method, instead, check the Collection Headers of the Request ASP.NET object as I specified at the top of this issue, and that's all.
Regards
Thanks @TomPallister for your help, finally I have the complete solution to generate, get, transform and send the claims with Ocelot to the internal Service Fabric (Microservices) as follow:
- First, in Identity Server 4 project, I made this code refactor in the ApiResource and Client definition:
public static IEnumerable<ApiResource> ApiResources() { return new List<ApiResource> { new ApiResource("socialnetwork", "Social Network") { // Define the claims that will use the Resource and generate in the Token UserClaims = new List<string> { "City", "State" } } }; } public static IEnumerable<Client> Clients() { return new[] { new Client { ClientId = "socialnetworkclient", AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, ClientSecrets = { new Secret("secret".Sha256()) }, AllowedScopes = { "socialnetwork" }, AccessTokenType = AccessTokenType.Jwt, // Specify that I want to include the claims in the same Token AlwaysSendClientClaims = true } }; } public static IEnumerable<TestUser> Users() { return new[] { new TestUser { SubjectId = "1", Username = "[email protected]", Password = "*******", Claims = new List<Claim> { new Claim("City", "Mexicali"), new Claim("State", "Baja California") } } }; }
- So, when I authenticate to the IdentityServer4 url endpoint
http://+/connect/tokenI confirm that the claims was returned in the Token, decoded with the help of https://jwt.io website as follow:
- Then I just modified the
configuration.jsonOcelot file with the specification as the docs says here with the following json code:{ "ReRoutes": [ { "DownstreamPathTemplate": "/{route}", "UpstreamPathTemplate": "/servicea/{route}", "UpstreamHttpMethod": [ "Get", "Post", "Put", "Patch", "Delete", "Options" ], "DownstreamScheme": "http", "ServiceName": "ServiceFabricApplication/ServiceA", "UseServiceDiscovery": true, "AuthenticationOptions": { "AuthenticationProviderKey": "TestKey", "AllowedScopes": [] }, // Here it is the instruction for the conversion of Claims // to request Headers "AddHeadersToRequest": { "claims_City": "Claims[City] > value > |", "claims_State": "Claims[State] > value > |" } }, { "DownstreamPathTemplate": "/{route}", "UpstreamPathTemplate": "/serviceoauth/{route}", "UpstreamHttpMethod": [ "Get", "Post", "Put", "Patch", "Delete", "Options" ], "DownstreamScheme": "http", "ServiceName": "ServiceFabricApplication/ServiceOAuth", "UseServiceDiscovery": true } ], "GlobalConfiguration": { "RequestIdKey": "OcRequestId", "AdministrationPath": "/administration", "ServiceDiscoveryProvider": { "Host": "localhost", "Port": 19081, "Type": "ServiceFabric" } } }
- And finally, when I send a request to the Ocelot service pointing to the microservice that needs authentication I received those claims in the headers of the request in the microservice like so:
That's all ... thanks again @TomPallister
Here it is the complete source code sample that I want to share for everyone GitHub Repository
AddHeadersToRequest add to headers, but AddClaimsToRequest is not adding to claims. see the below example
AddClaimsToRequest: {
"claims_Email": "Claims[Email] > value > |",
"claims_Name": "Claims[Name] > value > |"
}
In API project
(ClaimsIdentity)User.Identity doesn't have any claims.
@acheriya you have to parse token in order to use User.Identity with Claims.
In startup.cs of your microservice:
//ConfigureServices
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = CreateTokenValidationParameters();
});
...
private TokenValidationParameters CreateTokenValidationParameters() //we ignore token validation because gateway validates it
{
var result = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateIssuerSigningKey = false,
SignatureValidator = delegate (string token, TokenValidationParameters parameters)
{
var jwt = new JwtSecurityToken(token);
return jwt;
},
RequireExpirationTime = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
};
result.RequireSignedTokens = false;
return result;
}
Most helpful comment
Thanks @TomPallister for your help, finally I have the complete solution to generate, get, transform and send the claims with Ocelot to the internal Service Fabric (Microservices) as follow:
http://+/connect/tokenI confirm that the claims was returned in the Token, decoded with the help of https://jwt.io website as follow:configuration.jsonOcelot file with the specification as the docs says here with the following json code:That's all ... thanks again @TomPallister