IdentityServer4 自定义 AuthenticationHandler 找不到用户的所有声明
IdentityServer4 custom AuthenticationHandler can't find all claims for a user
我正在使用使用 Asp.Net Identity 和 EntityFramework.
的 IdentityServer4 示例
我正在尝试使用基于 claims/roles 的自定义策略创建组控件。
我的问题是,当我尝试在授权处理程序中获取用户声明时,我正在寻找的声明没有返回。
查看 SSMS 中的数据库,我发现我创建的 claims/roles 在 table 中称为 "AspNetRoles"、"AspNetRoleClaims"、"AspNetUserClaims" 以及我创建的用户在 "AspNetUsers" 中,用户和角色的密钥在 "AspNetUserRoles" 中。
当我打电话要求获得用户的授权声明时,声明列表似乎来自 "IdentityClaims" table.
似乎没有一种简单的方法来检查 "AspNetClaims" 中的声明,就像 "IdentityClaims" 中的声明一样,所以我假设我在某处犯了错误。
我四处寻找解决方案并尝试了一些方法,但找不到任何有效的方法。
下面是我认为与问题最相关的代码以及 运行 代码的一些屏幕截图。
任何帮助将不胜感激,在此先感谢。
代码
MvcClient.Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthorization(options =>
{
options.AddPolicy("AdminRights", policy =>
{
policy.Requirements.Add(new AdminRequirement());
policy.RequireAuthenticatedUser();
policy.AddAuthenticationSchemes("Cookies");
});
});
services.AddSingleton<IAuthorizationHandler, AdminRequirementHandler>();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.ClientSecret = "secret";
options.ResponseType = "code id_token token"; // NEW CHANGE (token)
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("api1");
options.Scope.Add("AdminPermission"); // NEW CHANGE
options.Scope.Add("offline_access");
});
}
MvcClient.Controllers.HomeController
[Authorize(Policy = "AdminRights")]
public IActionResult Administrator()
{
return View();
}
IdentityServerWithAspIdAndEF.Startup(在配置中最后调用)
private async Task CreateSuperuser(IServiceProvider serviceProvider, ApplicationDbContext context)
{
//adding custom roles
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
string[] roleNames = { "Administrator", "Internal", "Customer" };
foreach (var roleName in roleNames)
{
//creating the roles and seeding them to the database
var roleExist = await RoleManager.RoleExistsAsync(roleName);
if (roleExist)
await RoleManager.DeleteAsync( await RoleManager.FindByNameAsync(roleName) );
var newRole = new IdentityRole(roleName);
await RoleManager.CreateAsync(newRole);
if(roleName == "Administrator")
await RoleManager.AddClaimAsync(newRole, new Claim("AdminPermission", "Read"));
}
//creating a super user who could maintain the web app
var poweruser = new ApplicationUser
{
UserName = Configuration.GetSection("UserSettings")["UserEmail"],
Email = Configuration.GetSection("UserSettings")["UserEmail"]
};
string UserPassword = Configuration.GetSection("UserSettings")["UserPassword"];
var _user = await UserManager.FindByEmailAsync(Configuration.GetSection("UserSettings")["UserEmail"]);
if (_user != null)
await UserManager.DeleteAsync( await UserManager.FindByEmailAsync(Configuration.GetSection("UserSettings")["UserEmail"]) );
var createPowerUser = await UserManager.CreateAsync(poweruser, UserPassword);
if (createPowerUser.Succeeded)
{
//here we tie the new user to the "Admin" role
await UserManager.AddToRoleAsync(poweruser, "Administrator");
await UserManager.AddClaimAsync(poweruser, new Claim("AdminPermission", "Create"));
await UserManager.AddClaimAsync(poweruser, new Claim("AdminPermission", "Update"));
await UserManager.AddClaimAsync(poweruser, new Claim("AdminPermission", "Delete"));
}
}
IdentityServerWithAspIdAndEF.Config
public class Config
{
// scopes define the resources in your system
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResource() // NEW CHANGE
{
Name = "AdminPermission",
DisplayName = "Admin Permission",
UserClaims =
{
"AdminPermission",
}
}
};
}
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api1", "My API")
{
Scopes = // NEW CHANGE
{
new Scope("AdminPermission", "Admin Permission")
{
UserClaims = { "AdminPermission" }
}
}
}
};
}
// clients want to access resources (aka scopes)
public static IEnumerable<Client> GetClients()
{
// client credentials client
return new List<Client>
{
// OpenID Connect hybrid flow and client credentials client (MVC)
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RequireConsent = false, // NEW CHANGE (false)
ClientSecrets =
{
new Secret("secret".Sha256())
},
RedirectUris = { "http://localhost:5002/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
"AdminPermission", // NEW CHANGE
},
AllowOfflineAccess = true,
},
// Other Clients omitted as not used.
};
}
}
IdentityServerWithAspIdAndEF.Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
services.AddMvc();
string connectionString = Configuration.GetConnectionString("DefaultConnection");
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
// configure identity server with in-memory stores, keys, clients and scopes
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddAspNetIdentity<ApplicationUser>()
// this adds the config data from DB (clients, resources)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 30;
});
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.ClientId = "434483408261-55tc8n0cs4ff1fe21ea8df2o443v2iuc.apps.googleusercontent.com";
options.ClientSecret = "3gcoTrEDPPJ0ukn_aYYT6PWo";
})
.AddOpenIdConnect("oidc", "OpenID Connect", options =>
{
options.Authority = "https://demo.identityserver.io/";
options.ClientId = "implicit";
options.SaveTokens = true;
// options.GetClaimsFromUserInfoEndpoint = true; // NEW CHANGE
// options.ResponseType = "code id_token token"; // NEW CHANGE
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
});
}
MvcClient.Authorization
public class AdminRequirementHandler : AuthorizationHandler<AdminRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AdminRequirement requirement)
{
Console.WriteLine("User Identity: {0}", context.User.Identity);
Console.WriteLine("Role is 'Administrator'? : {0}", context.User.IsInRole("Administrator"));
Console.WriteLine("Identities of user:-");
foreach (var v in context.User.Identities)
{
Console.WriteLine("\tName: {0},\tActor: {1},\tAuthType: {2},\tIsAuth: {3}", v.Name, v.Actor, v.AuthenticationType, v.IsAuthenticated);
Console.WriteLine("\n\tClaims from Identity:-");
foreach (var c in v.Claims)
Console.WriteLine("\t\tType: {0},\tValue: {1},\tSubject: {2},\tIssuer: {3}", c.Type, c.Value, c.Subject, c.Issuer);
}
Console.WriteLine("Claims from other source:-");
foreach(Claim c in context.User.Claims)
{
Console.WriteLine("\t\tType: {0},\tValue: {1},\tSubject: {2},\tIssuer: {3}", c.Type, c.Value, c.Subject, c.Issuer);
}
Console.WriteLine("\n *** Starting Authroization. ***\n");
Claim
role = context.User.FindFirst("role"),
accessLevel = context.User.FindFirst("AdminPermission");
if (role == null)
Console.WriteLine("\tUser as no 'role' : '{0}'", role == null ? "null" : role.Value);
else
Console.WriteLine("\tUser has 'role' : '{0}'", role.Value);
if (accessLevel == null)
Console.WriteLine("\tUser has no claim 'AdminPermission' : '{0}'", accessLevel == null ? "null" : accessLevel.Value);
else
Console.WriteLine("\tUser has 'AdminPermission' : '{0}'", accessLevel.Value);
if (role != null && accessLevel != null)
{
if (role.Value == "Administrator" && accessLevel.Value == "Read")
context.Succeed(requirement);
}
else
Console.WriteLine("\n *** Authorization Failue. ***\n");
return Task.CompletedTask;
}
}
数据
ApiClaims :
ApiResources : api1
ApiScopeClaims : AdminPermission, ApiScopeId = 2
ApiScopes : api1, ApiResourceId = 1
: AdminPermission, ApiResourceId = 1
ApiSecrets :
AspNetRoleClaims : AdminPermission, Read, RoleId = b2f03...
AspNetRoles : Administrator, b2f03...
: Customer, 779f7...
: Internal, 10d5d...
AspNetUserClaims : AdminPermission, Create, UserId = 8ee62...
: AdminPermission, Update, UserId = 8ee62...
: AdminPermission, Delete, UserId = 8ee62...
AspNetUserLogins :
AspNetUserRoles : UserId = 8ee62..., RoleId = b2f03...
AspNetUsers : superuser@mail.com, Id = 8ee62...
AspNetUserTokens :
ClientClaims :
ClientCorsOrigins :
ClientGrantTypes : hybrid, ClientId = 1
: client_credentials, ClientId = 1
: client_credentials, ClientId = 2
: password, ClientId = 3
ClientIdPRestrictions :
ClientPostLogoutRedirectUris : http://localhost:5002/signout-callback-oidc, ClientId = 1
ClientProperties :
ClientRedirectUris : http://localhost:5002/signin-oidc, ClientId = 1
Clients : mvc, AllowAccessTokenViaBrowser = 1, AllowOfflineAccess = 1, RequireConsent = 0
: client ...
: ro.client ...
ClientScopes : openid, ClientId = 1
: profile, ClientId = 1
: AdminPermission, ClientId = 1
ClientSecrets : Type = SharedSecret
IdentityClaims : Id IdentityResourceId Type
1 1 sub
2 2 name
3 2 family_name
4 2 given_name
5 2 middle_name
6 2 nickname
7 2 preferred_username
8 2 profile
9 2 picture
10 2 website
11 2 gender
12 2 birthdate
13 2 zoneinfo
14 2 locale
15 2 updated_at
16 3 AdminPermission
IdentityResources : openid
: profile
: AdminPermission
PersistedGrants : [8x] Type = refresh_token
图片
Autos at the beginning of the AuthorizationHandler
Claims shown on the identity server
Claims shows on the MVC client
Log from when an authenticate user attempts to access
JWT received by MVC client
Database tables
--编辑--
我已经分叉了你的代码并解决了这个问题。
这是我的回购 link。
https://github.com/derekrivers/IdentityServer4
为了修复您的解决方案,我也更改了服务器身份验证响应类型:-
"code Id_token"
在您 config.cs 的 MVC 客户端设置中,我添加了以下属性 :-
AlwaysSendClientClaims = true,
AlwaysIncludeUserClaimsInIdToken = true
我还从 mvc 客户端中删除了 adminpermission 范围,因为它不是必需的。
我还稍微修改了 AdminRequirementHandler.cs,但我会让您在我的回购中探索它。
基本上,我们已经确保用户声明在身份令牌中,通过这样做,他们可以在您内部访问 AdminRequirementHandler
希望对您有所帮助。
我正在使用使用 Asp.Net Identity 和 EntityFramework.
的 IdentityServer4 示例我正在尝试使用基于 claims/roles 的自定义策略创建组控件。
我的问题是,当我尝试在授权处理程序中获取用户声明时,我正在寻找的声明没有返回。
查看 SSMS 中的数据库,我发现我创建的 claims/roles 在 table 中称为 "AspNetRoles"、"AspNetRoleClaims"、"AspNetUserClaims" 以及我创建的用户在 "AspNetUsers" 中,用户和角色的密钥在 "AspNetUserRoles" 中。 当我打电话要求获得用户的授权声明时,声明列表似乎来自 "IdentityClaims" table.
似乎没有一种简单的方法来检查 "AspNetClaims" 中的声明,就像 "IdentityClaims" 中的声明一样,所以我假设我在某处犯了错误。
我四处寻找解决方案并尝试了一些方法,但找不到任何有效的方法。
下面是我认为与问题最相关的代码以及 运行 代码的一些屏幕截图。
任何帮助将不胜感激,在此先感谢。
代码
MvcClient.Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthorization(options =>
{
options.AddPolicy("AdminRights", policy =>
{
policy.Requirements.Add(new AdminRequirement());
policy.RequireAuthenticatedUser();
policy.AddAuthenticationSchemes("Cookies");
});
});
services.AddSingleton<IAuthorizationHandler, AdminRequirementHandler>();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.ClientSecret = "secret";
options.ResponseType = "code id_token token"; // NEW CHANGE (token)
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("api1");
options.Scope.Add("AdminPermission"); // NEW CHANGE
options.Scope.Add("offline_access");
});
}
MvcClient.Controllers.HomeController
[Authorize(Policy = "AdminRights")]
public IActionResult Administrator()
{
return View();
}
IdentityServerWithAspIdAndEF.Startup(在配置中最后调用)
private async Task CreateSuperuser(IServiceProvider serviceProvider, ApplicationDbContext context)
{
//adding custom roles
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
string[] roleNames = { "Administrator", "Internal", "Customer" };
foreach (var roleName in roleNames)
{
//creating the roles and seeding them to the database
var roleExist = await RoleManager.RoleExistsAsync(roleName);
if (roleExist)
await RoleManager.DeleteAsync( await RoleManager.FindByNameAsync(roleName) );
var newRole = new IdentityRole(roleName);
await RoleManager.CreateAsync(newRole);
if(roleName == "Administrator")
await RoleManager.AddClaimAsync(newRole, new Claim("AdminPermission", "Read"));
}
//creating a super user who could maintain the web app
var poweruser = new ApplicationUser
{
UserName = Configuration.GetSection("UserSettings")["UserEmail"],
Email = Configuration.GetSection("UserSettings")["UserEmail"]
};
string UserPassword = Configuration.GetSection("UserSettings")["UserPassword"];
var _user = await UserManager.FindByEmailAsync(Configuration.GetSection("UserSettings")["UserEmail"]);
if (_user != null)
await UserManager.DeleteAsync( await UserManager.FindByEmailAsync(Configuration.GetSection("UserSettings")["UserEmail"]) );
var createPowerUser = await UserManager.CreateAsync(poweruser, UserPassword);
if (createPowerUser.Succeeded)
{
//here we tie the new user to the "Admin" role
await UserManager.AddToRoleAsync(poweruser, "Administrator");
await UserManager.AddClaimAsync(poweruser, new Claim("AdminPermission", "Create"));
await UserManager.AddClaimAsync(poweruser, new Claim("AdminPermission", "Update"));
await UserManager.AddClaimAsync(poweruser, new Claim("AdminPermission", "Delete"));
}
}
IdentityServerWithAspIdAndEF.Config
public class Config
{
// scopes define the resources in your system
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResource() // NEW CHANGE
{
Name = "AdminPermission",
DisplayName = "Admin Permission",
UserClaims =
{
"AdminPermission",
}
}
};
}
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api1", "My API")
{
Scopes = // NEW CHANGE
{
new Scope("AdminPermission", "Admin Permission")
{
UserClaims = { "AdminPermission" }
}
}
}
};
}
// clients want to access resources (aka scopes)
public static IEnumerable<Client> GetClients()
{
// client credentials client
return new List<Client>
{
// OpenID Connect hybrid flow and client credentials client (MVC)
new Client
{
ClientId = "mvc",
ClientName = "MVC Client",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
RequireConsent = false, // NEW CHANGE (false)
ClientSecrets =
{
new Secret("secret".Sha256())
},
RedirectUris = { "http://localhost:5002/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
"AdminPermission", // NEW CHANGE
},
AllowOfflineAccess = true,
},
// Other Clients omitted as not used.
};
}
}
IdentityServerWithAspIdAndEF.Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
services.AddMvc();
string connectionString = Configuration.GetConnectionString("DefaultConnection");
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
// configure identity server with in-memory stores, keys, clients and scopes
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddAspNetIdentity<ApplicationUser>()
// this adds the config data from DB (clients, resources)
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
// this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 30;
});
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.ClientId = "434483408261-55tc8n0cs4ff1fe21ea8df2o443v2iuc.apps.googleusercontent.com";
options.ClientSecret = "3gcoTrEDPPJ0ukn_aYYT6PWo";
})
.AddOpenIdConnect("oidc", "OpenID Connect", options =>
{
options.Authority = "https://demo.identityserver.io/";
options.ClientId = "implicit";
options.SaveTokens = true;
// options.GetClaimsFromUserInfoEndpoint = true; // NEW CHANGE
// options.ResponseType = "code id_token token"; // NEW CHANGE
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
});
}
MvcClient.Authorization
public class AdminRequirementHandler : AuthorizationHandler<AdminRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AdminRequirement requirement)
{
Console.WriteLine("User Identity: {0}", context.User.Identity);
Console.WriteLine("Role is 'Administrator'? : {0}", context.User.IsInRole("Administrator"));
Console.WriteLine("Identities of user:-");
foreach (var v in context.User.Identities)
{
Console.WriteLine("\tName: {0},\tActor: {1},\tAuthType: {2},\tIsAuth: {3}", v.Name, v.Actor, v.AuthenticationType, v.IsAuthenticated);
Console.WriteLine("\n\tClaims from Identity:-");
foreach (var c in v.Claims)
Console.WriteLine("\t\tType: {0},\tValue: {1},\tSubject: {2},\tIssuer: {3}", c.Type, c.Value, c.Subject, c.Issuer);
}
Console.WriteLine("Claims from other source:-");
foreach(Claim c in context.User.Claims)
{
Console.WriteLine("\t\tType: {0},\tValue: {1},\tSubject: {2},\tIssuer: {3}", c.Type, c.Value, c.Subject, c.Issuer);
}
Console.WriteLine("\n *** Starting Authroization. ***\n");
Claim
role = context.User.FindFirst("role"),
accessLevel = context.User.FindFirst("AdminPermission");
if (role == null)
Console.WriteLine("\tUser as no 'role' : '{0}'", role == null ? "null" : role.Value);
else
Console.WriteLine("\tUser has 'role' : '{0}'", role.Value);
if (accessLevel == null)
Console.WriteLine("\tUser has no claim 'AdminPermission' : '{0}'", accessLevel == null ? "null" : accessLevel.Value);
else
Console.WriteLine("\tUser has 'AdminPermission' : '{0}'", accessLevel.Value);
if (role != null && accessLevel != null)
{
if (role.Value == "Administrator" && accessLevel.Value == "Read")
context.Succeed(requirement);
}
else
Console.WriteLine("\n *** Authorization Failue. ***\n");
return Task.CompletedTask;
}
}
数据
ApiClaims :
ApiResources : api1
ApiScopeClaims : AdminPermission, ApiScopeId = 2
ApiScopes : api1, ApiResourceId = 1
: AdminPermission, ApiResourceId = 1
ApiSecrets :
AspNetRoleClaims : AdminPermission, Read, RoleId = b2f03...
AspNetRoles : Administrator, b2f03...
: Customer, 779f7...
: Internal, 10d5d...
AspNetUserClaims : AdminPermission, Create, UserId = 8ee62...
: AdminPermission, Update, UserId = 8ee62...
: AdminPermission, Delete, UserId = 8ee62...
AspNetUserLogins :
AspNetUserRoles : UserId = 8ee62..., RoleId = b2f03...
AspNetUsers : superuser@mail.com, Id = 8ee62...
AspNetUserTokens :
ClientClaims :
ClientCorsOrigins :
ClientGrantTypes : hybrid, ClientId = 1
: client_credentials, ClientId = 1
: client_credentials, ClientId = 2
: password, ClientId = 3
ClientIdPRestrictions :
ClientPostLogoutRedirectUris : http://localhost:5002/signout-callback-oidc, ClientId = 1
ClientProperties :
ClientRedirectUris : http://localhost:5002/signin-oidc, ClientId = 1
Clients : mvc, AllowAccessTokenViaBrowser = 1, AllowOfflineAccess = 1, RequireConsent = 0
: client ...
: ro.client ...
ClientScopes : openid, ClientId = 1
: profile, ClientId = 1
: AdminPermission, ClientId = 1
ClientSecrets : Type = SharedSecret
IdentityClaims : Id IdentityResourceId Type
1 1 sub
2 2 name
3 2 family_name
4 2 given_name
5 2 middle_name
6 2 nickname
7 2 preferred_username
8 2 profile
9 2 picture
10 2 website
11 2 gender
12 2 birthdate
13 2 zoneinfo
14 2 locale
15 2 updated_at
16 3 AdminPermission
IdentityResources : openid
: profile
: AdminPermission
PersistedGrants : [8x] Type = refresh_token
图片
Autos at the beginning of the AuthorizationHandler
Claims shown on the identity server
Claims shows on the MVC client
Log from when an authenticate user attempts to access
JWT received by MVC client
Database tables
--编辑--
我已经分叉了你的代码并解决了这个问题。
这是我的回购 link。
https://github.com/derekrivers/IdentityServer4
为了修复您的解决方案,我也更改了服务器身份验证响应类型:-
"code Id_token"
在您 config.cs 的 MVC 客户端设置中,我添加了以下属性 :-
AlwaysSendClientClaims = true,
AlwaysIncludeUserClaimsInIdToken = true
我还从 mvc 客户端中删除了 adminpermission 范围,因为它不是必需的。
我还稍微修改了 AdminRequirementHandler.cs,但我会让您在我的回购中探索它。
基本上,我们已经确保用户声明在身份令牌中,通过这样做,他们可以在您内部访问 AdminRequirementHandler
希望对您有所帮助。