I am trying to setup Ocelot in an Api Gateway and I am stuck on Authorization. I have managed to setup claims and I can authorize with them inside my controllers. I add a claim to a user like this:
await userManager.AddClaimAsync(user, new Claim(ClaimTypes.Role, configuration["InitialAdmin:Role"]));
Then I setup Ocelot with the following config:
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/api/home/user",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/api/home/user",
"RouteClaimsRequirement": {
"Role": "user"
}
},
{
"DownstreamPathTemplate": "/api/home/admin",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/api/home/admin",
"RouteClaimsRequirement": {
"Role": "SuperAdmin"
}
}
],
"GlobalConfiguration": {
"BaseUrl": "https://localhost:5000"
}
}
Here is my ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddIdentity<CondatoUser, IdentityRole>(options =>
{
//Signin config
options.SignIn.RequireConfirmedEmail = true;
//Password config
options.Password.RequiredLength = 8;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
//User config
options.User.RequireUniqueEmail = true;
})
.AddDefaultUI()
.AddEntityFrameworkStores<UserManagementDbContext>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddOcelot(Configuration);
}
I then log into this gateway Api (It's a MVC project with the default UI for login/register/etc.) and try to visit the following URL:
https://localhost:5000/api/home/admin
However, I always get a 403 status back. When I remove RouteClaimsRequirement
, it works. So I guess I am missing something, but I have no idea how as the documentation for RouteClaimsRequirement
is a little sparse.
Can anybody help me out here? Thanks.
Well it turns out that this can't be done using the predefined ClaimTypes
in System.Security.Claims
. Which is due to the fact that (app)settings json parsing can't handle a colon (:) in a dictionary key. Referring to this issue on the Ocelot repo.
The solution is to use a custom claim type, e.g. "Role" instead of System.Security.Claims.Role
, which yields "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"