I have a service called Catalog. When I make a request as follows to access this service normally and take courses through the service, the request is answered successfully.
localhost:5011/api/courses
When I make the following request to receive all courses through the gateway, it returns with a 403 status code. For this I make a request as follows:
http://localhost:5000/services/catalog/courses
As a result, the same request is not responded to via the gateway.
Program.cs File of my Gateway project:
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication().AddJwtBearer("GatewayAuthenticationScheme",options =>
{
options.Authority = builder.Configuration["IdentityServerUrl"];
options.Audience = "resource_gateway";
options.RequireHttpsMetadata = false;
});
builder.Configuration.AddJsonFile($"configuration.{builder.Environment.EnvironmentName.ToString().ToLower()}.json");
builder.Services.AddOcelot();
var app = builder.Build();
app.UseAuthorization();
await app.UseOcelot();
app.Run();
Gateway is waiting for resource_gateway audience.
This audience is included in the token I sent.
The Config.cs file for the Identity server is as follows:
using System;
using IdentityServer4.Models;
using System.Collections.Generic;
using IdentityServer4;
namespace FreeCourse.IdentityServer
{
public static class Config
{
public static IEnumerable<ApiResource> ApiResources =>
new ApiResource[]
{
new ApiResource("resource_catalog") { Scopes = { "catalog_fullpermission" } },
new ApiResource("resource_photo_stock") { Scopes = { "photo_stock_fullpermission" } },
new ApiResource("resource_basket") { Scopes = { "basket_fullpermission" } },
new ApiResource("resource_discount") { Scopes = { "discount_fullpermission" } },
new ApiResource("resource_order") { Scopes = { "order_fullpermission" } },
new ApiResource("resource_payment") { Scopes = { "payment_fullpermission" } },
new ApiResource("resource_gateway") { Scopes = { "gateway_fullpermission" } },
new ApiResource(IdentityServerConstants.LocalApi.ScopeName)
};
public static IEnumerable<IdentityResource> IdentityResources =>
new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Email(),
new IdentityResources.Profile(),
new IdentityResource()
{ Name = "roles", DisplayName = "Roles", Description = "User roles", UserClaims = new[] { "role" } }
};
public static IEnumerable<ApiScope> ApiScopes =>
new ApiScope[]
{
new ApiScope("catalog_fullpermission", "full access permission for Catalog API "),
new ApiScope("photo_stock_fullpermission", "full access permission for PhotoStock API "),
new ApiScope("basket_fullpermission", "full access permission for Basket API "),
new ApiScope("discount_fullpermission", "full access permission for Discount API "),
new ApiScope("order_fullpermission", "full access permission for Order API "),
new ApiScope("payment_fullpermission", "full access permission for Payment API"),
new ApiScope("gateway_fullpermission", "full access permission for Gateway API"),
new ApiScope(IdentityServerConstants.LocalApi.ScopeName)
};
public static IEnumerable<Client> Clients =>
new Client[]
{
new Client
{
ClientName = "Asp.Net Core MVC",
ClientId = "WebMvcClient",
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes =
{
"catalog_fullpermission", "photo_stock_fullpermission", "gateway_fullpermission",
IdentityServerConstants.LocalApi.ScopeName
}
},
new Client
{
ClientName = "Asp.Net Core MVC",
ClientId = "WebMvcClientForUser",
AllowOfflineAccess = true,
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
AllowedScopes =
{
"gateway_fullpermission",
"basket_fullpermission",
"discount_fullpermission",
"order_fullpermission",
"payment_fullpermission",
"catalog_fullpermission",
"photo_stock_fullpermission",
"gateway_fullpermission",
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes
.OfflineAccess,
IdentityServerConstants.LocalApi.ScopeName,
"roles"
},
AccessTokenLifetime = 1 * 60 * 60,
RefreshTokenExpiration = TokenExpiration.Absolute,
AbsoluteRefreshTokenLifetime =
(int)(DateTime.Now.AddDays(60) - DateTime.Now).TotalSeconds, // 60 gun
RefreshTokenUsage = TokenUsage.ReUse,
}
};
}
}
Ocelot configuration file:
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5011
}
],
"UpstreamPathTemplate": "/services/catalog/{everything}",
"UpstreamHttpMethod": [
"Get",
"Post",
"Put",
"Delete"
],
"UpstreamScheme": "http",
"AuthenticationOptions": {
"AuthenticationProviderKey": "GatewayAuthenticationScheme",
"AllowedScopes": ["catalog_fullpermission"]
}
},
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5012
}
],
"UpstreamPathTemplate": "/services/photostock/{everything}",
"UpstreamHttpMethod": [
"Get",
"Post",
"Put",
"Delete"
],
"UpstreamScheme": "http",
"AuthenticationOptions": {
"AuthenticationProviderKey": "GatewayAuthenticationScheme",
"AllowedScopes": ["photostock_fullpermission"]
}
},
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5013
}
],
"UpstreamPathTemplate": "/services/basket/{everything}",
"UpstreamHttpMethod": [
"Get",
"Post",
"Put",
"Delete"
],
"UpstreamScheme": "http",
"AuthenticationOptions": {
"AuthenticationProviderKey": "GatewayAuthenticationScheme",
"AllowedScopes": ["basket_fullpermission"]
}
},
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5014
}
],
"UpstreamPathTemplate": "/services/discount/{everything}",
"UpstreamHttpMethod": [
"Get",
"Post",
"Put",
"Delete"
],
"UpstreamScheme": "http",
"AuthenticationOptions": {
"AuthenticationProviderKey": "GatewayAuthenticationScheme",
"AllowedScopes": ["discount_fullpermission"]
}
},
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5015
}
],
"UpstreamPathTemplate": "/services/order/{everything}",
"UpstreamHttpMethod": [
"Get",
"Post",
"Put",
"Delete"
],
"UpstreamScheme": "http",
"AuthenticationOptions": {
"AuthenticationProviderKey": "GatewayAuthenticationScheme",
"AllowedScopes": ["order_fullpermission"]
}
},
{
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5016
}
],
"UpstreamPathTemplate": "/services/payment/{everything}",
"UpstreamHttpMethod": [
"Get",
"Post",
"Put",
"Delete"
],
"UpstreamScheme": "http",
"AuthenticationOptions": {
"AuthenticationProviderKey": "GatewayAuthenticationScheme",
"AllowedScopes": ["payment_fullpermission"]
}
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:5000"
}
}
I checked the token I sent on jwt.io. The token contains "resource_gateway". I can't understand the problem.
Thank you very much.
The problem was caused by the identity server not being up to date. After updating, the problem went away.