Hi All,
I've followed the below article link to authenticate API gateway using Ocelot. I use .Net core 2.1 When I run the application the API wasn't authenticated and shows the result as NOTFOUNDas shown below.
https://www.c-sharpcorner.com/article/building-api-gateway-using-ocelot-in-asp-net-core-part-two/
Start of Result___________________________________________
Result:
Sending Request to /products , without token.
Result : Unauthorized
Begin Auth....
End Auth....
Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJrYW1hbCIsImp0aSI6ImU4MTViOTg2LTUwZjYtNDcwNy04OTE0LTljMDZmZTljNjRkOSIsImlhdCI6IjgvMzAvMjAxOCAyOjI1OjM3IFBNIiwibmJmIjoxNTM1NjM5MTM3LCJleHAiOjE1MzU2MzkyNTd9.HkTHZdlyPGA6EfyjjQfwPXAddYjpCPypZBhW3-m-uhU
Send Request to /products , with token.
Result : NotFound
End of Result______________________________________________
Here is the code:
APIGateway
configuration.json
{
"DownstreamPathTemplate": "/api/products",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 9002
}
],
"UpstreamPathTemplate": "/api/products",
"UpstreamHttpMethod": [ "Get" ],
"AuthenticationOptions": {
"AuthenticationProviderKey": "TestKey",
"AllowedScopes": []
}
}
ProductController.cs
[Route("api/[controller]")]
public class ProductsController : Controller
{
[Authorize]
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "Data-1", "Data-2" };
}
}
Startup.cs
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
Action<ConfigurationBuilderCachePart> settings = (x) =>
{
x.WithMicrosoftLogging(log =>
{
log.AddConsole(LogLevel.Debug);
}).WithDictionaryHandle();
};
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA=="));
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateIssuer = true,
ValidIssuer = audienceConfig["Iss"],
ValidateAudience = true,
ValidAudience = audienceConfig["Aud"],
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
RequireExpirationTime = true,
};
var authenticationProviderKey = "TestKey";
services.AddAuthentication()
.AddJwtBearer(authenticationProviderKey, x =>
{
x.RequireHttpsMetadata = false;
x.TokenValidationParameters = tokenValidationParameters;
});
services.AddOcelot(Configuration);
}
Controller generates TOKEN
[HttpGet]
public IActionResult Get(string name, string pwd)
{
if (name == "test" && pwd == "abc123")
{
var now = DateTime.UtcNow;
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, name),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, now.ToUniversalTime().ToString(), ClaimValueTypes.Integer64)
};
var signingKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.ASCII.GetBytes("Y2F0Y2hlciUyMHdvbmclMjBsb3ZlJTIwLm5ldA=="));
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateIssuer = true,
ValidIssuer = _settings.Value.Iss,
ValidateAudience = true,
ValidAudience = _settings.Value.Aud,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
RequireExpirationTime = true,
};
var jwt = new JwtSecurityToken(
issuer: _settings.Value.Iss,
audience: _settings.Value.Aud,
claims: claims,
notBefore: now,
expires: now.Add(TimeSpan.FromMinutes(2)),
signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
var responseJson = new
{
access_token = encodedJwt,
expires_in = (int)TimeSpan.FromMinutes(2).TotalSeconds
};
return Json(responseJson);
}
else
{
return Json("Invalid credentials");
}
}
Thanks,
Anand