'With identityserver4, read, write, delete operations according to the user's authority
I am authenticating with identityserver4. I am using database sql server. I have completed migration processes, user registration and user authorizations.
There is a user I have specified and I have not given the user read permission.
I reported this to the API side, but it can read even if the user has no authorization.
How can I fix this? [Authorize(Policy = "ReadPurchasingManagement")]
I coded the config file as follows Config.cs
using IdentityModel;
using IdentityServer4;
using IdentityServer4.Models;
using System;
using System.Collections.Generic;
namespace IdentityServer
{
public static class Config
{
#region ApiResources
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>() {
new ApiResource("resource_purchasing"){Scopes= {"purchasing.create", "purchasing.read", "purchasing.update", "purchasing.delete"}},
new ApiResource(IdentityServerConstants.LocalApi.ScopeName)
};
}
#endregion
#region Identity Resource
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>()
{
new IdentityResources.OpenId(),
new IdentityResources.Email(),
new IdentityResources.Profile(),
new IdentityResources.Phone(),
new IdentityResources.Address(),
new IdentityResource()
{
Name="roles",
DisplayName="Roles",
Description= "User roles",
UserClaims = { JwtClaimTypes.Role },
}
};
}
#endregion
#region Scopes
public static IEnumerable<ApiScope> GetApiScope()
{
return new List<ApiScope>()
{
#region Purchasing Management Permissions
new ApiScope("purchasing.create", "PM create"),
new ApiScope("purchasing.read", "PM read"),
new ApiScope("purchasing.update", "PM update"),
new ApiScope("purchasing.delete", "PM delete"),
new ApiScope(IdentityServerConstants.LocalApi.ScopeName),
#endregion
};
}
#endregion
#region Clients
public static IEnumerable<Client> GetClients()
{
return new List<Client>()
{
new Client()
{
ClientId = "PurchasingClient",
ClientSecrets = new[] { new Secret("secret".Sha256())},
ClientName = "Purchasing Management",
AllowedGrantTypes= GrantTypes.ResourceOwnerPasswordAndClientCredentials,
Enabled = true,
AccessTokenType = AccessTokenType.Jwt,
AlwaysSendClientClaims = true,
UpdateAccessTokenClaimsOnRefresh = true,
AlwaysIncludeUserClaimsInIdToken = true,
AllowAccessTokensViaBrowser = true,
IncludeJwtId = true,
AllowedScopes = {
IdentityServerConstants.LocalApi.ScopeName,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Phone,
IdentityServerConstants.StandardScopes.Address,
IdentityServerConstants.StandardScopes.OfflineAccess,
IdentityServerConstants.LocalApi.ScopeName,
"roles",
"resource_purchasing",
"purchasing.create",
"purchasing.read",
"purchasing.update",
"purchasing.delete"
},
AllowOfflineAccess=true,
AccessTokenLifetime= 4*60*60,
RefreshTokenExpiration=TokenExpiration.Absolute,
AbsoluteRefreshTokenLifetime=(int)(DateTime.Now.AddDays(60)-DateTime.Now).TotalSeconds,
RefreshTokenUsage = TokenUsage.ReUse
}
};
}
#endregion
}
}
Startup.cs
using IdentityServer.Data;
using IdentityServer.Models;
using IdentityServer.Services;
using IdentityServer4;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Reflection;
namespace IdentityServer
{
public class Startup
{
public IWebHostEnvironment Environment { get; }
public IConfiguration Configuration { get; }
public Startup(IWebHostEnvironment environment, IConfiguration configuration)
{
Environment = environment;
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalApiAuthentication();
services.AddControllersWithViews();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("IdentityServerDbConnection")));
#region Identity Roles
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 2;
options.Password.RequireNonAlphanumeric = false;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
#endregion
#region Identity Server Configuration
var assemblyName = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
var builder = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
options.EmitStaticAudienceClaim = true;
})
.AddConfigurationStore(opts =>
{
opts.ConfigureDbContext = c => c.UseSqlServer(Configuration.GetConnectionString("IdentityServerDbConnection"), sqlOptions => sqlOptions.MigrationsAssembly(assemblyName));
})
.AddOperationalStore(opts => (refresh token, authorization code)
{
opts.ConfigureDbContext = c => c.UseSqlServer(Configuration.GetConnectionString("IdentityServerDbConnection"), sqlOptions => sqlOptions.MigrationsAssembly(assemblyName));
})
.AddDeveloperSigningCredential()
.AddAspNetIdentity<ApplicationUser>()
.AddResourceOwnerValidator<IdentityResourceOwnerPasswordValidator>();
#endregion
services.AddAuthentication()
.AddGoogle(options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = "DynamicBoxWorkflow";
options.ClientSecret = "secret";
});
builder.AddDeveloperSigningCredential();
}
public void Configure(IApplicationBuilder app)
{
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
}
}
I made a definition like this on the client API side. But the user does not have permission, but he can read even though he is not authorized.
Client API
#region Identity Server 4 -> JWT Auth
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.Authority = builder.Configuration["IdentityServer:Authority"];
options.Audience = "resource_purchasing";
options.RequireHttpsMetadata = false;
});
#region Authorization - Claims
builder.Services.AddAuthorization(opts =>
{
opts.AddPolicy("CreatePurchasingManagement", policy =>
{
policy.RequireClaim("scope", new[] { "purchasing.create" });
});
opts.AddPolicy("ReadPurchasingManagement", policy =>
{
policy.RequireClaim("scope", new[] { "purchasing.read" });
});
opts.AddPolicy("UpdatePurchasingManagement", policy =>
{
policy.RequireClaim("scope", new[] { "purchasing.update" });
});
opts.AddPolicy("DeletePurchasingManagement", policy =>
{
policy.RequireClaim("scope", new[] { "purchasing.delete" });
});
});
#endregion
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|


