IdentityServer4 和 .net Core Identity - 传递/访问声明
IdentityServer4 and .net Core Identity - Passing/ accessing claims
我在不同的项目中有一个工作的 IdentityServer 和 MVC 客户端,我还在我的 asp.net 身份表中存储了针对角色的声明,这是我的种子数据代码,然后分配给用户:
if (await _roleManager.FindByNameAsync("Trainer") == null)
{
//Add Traininer Role
var trainerRole = new IdentityRole("Trainer");
await _roleManager.CreateAsync(trainerRole);
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.viewrelated"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.updatestatus"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "contacts.viewrelated"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "locations.viewrelated"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.delete"));
}
if (await _roleManager.FindByNameAsync("Booking Management") == null)
{
//Add Traininer Role
var trainerRole = new IdentityRole("Booking Management");
await _roleManager.CreateAsync(trainerRole);
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "companies.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "companies.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "companies.edit"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "companies.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "locations.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "locations.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "locations.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "locations.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "contacts.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "contacts.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "contacts.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "contacts.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.updatestatus"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.cancel"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "courses.view"));
}
if (await _roleManager.FindByNameAsync("Management") == null)
{
//Add Traininer Role
var trainerRole = new IdentityRole("Management");
await _roleManager.CreateAsync(trainerRole);
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "reporting.finance"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "reporting.customers"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "users.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "users.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "users.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "users.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "config.view"));
}
if (await _roleManager.FindByNameAsync("Course Management") == null)
{
//Add Traininer Role
var trainerRole = new IdentityRole("Course Management");
await _roleManager.CreateAsync(trainerRole);
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "courses.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "courses.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "courses.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "courses.delete"));
}
if (await _roleManager.FindByNameAsync("Admin") == null)
{
//Add Traininer Role
var trainerRole = new IdentityRole("Admin");
await _roleManager.CreateAsync(trainerRole);
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "config.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "config.update"));
}
当我登录身份服务器时,我的权限是列表
当我使用我的 MVC 客户端登录时,我没有获得用户权限
在我的 MVC 客户端中,我希望能够在我的导航中执行类似的操作
@if (user.HasClaim(CustomClaimTypes.Permission, "config.view"))
{
<li>
<a href="#"><i class="fa fa-cogs"></i> <span class="nav-label" data-i18n="nav.layouts">Configuration Settings</span></a>
<ul class="nav nav-second-level collapse">
<li>
<a href="/configuration#!/awardingbodies/"> <span class="nav-label" data-i18n="nav.layouts">Awarding Bodies</span></a>
</li>
</ul>
</li>
}
理想情况下,我假设检查权限您不想不断查询数据库,所以我假设最好使用令牌获取权限,但我不知道该怎么做?
编辑 1:Identity Server 中客户端的配置 (Config.cs)
new Client
{
ClientId = "webclientmvc",
ClientName = "CRM MVC Client",
AllowedGrantTypes = GrantTypes.Hybrid,
AlwaysSendClientClaims = true,
RequireConsent = true,
ClientSecrets =
{
new Secret("secret".Sha256())
},
RedirectUris = { "http://localhost:5009/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:5009" },
AllowedScopes =
{
StandardScopes.OpenId.Name,
StandardScopes.Profile.Name,
StandardScopes.OfflineAccess.Name,
StandardScopes.Roles.Name,
StandardScopes.AllClaims.Name,
"api1",
"claims"
}
},
在 MVC 客户端中配置 (startup.cs)
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
AutomaticChallenge = true,
AutomaticAuthenticate = true,
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ClientId = "webclientmvc",
ClientSecret = "secret",
ResponseType = "code id_token",
Scope = { "profile", "api1", "offline_access", "roles" },
GetClaimsFromUserInfoEndpoint = true,
SaveTokens = true
});
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
我现在已经开始工作了,但想知道是否有人可以评论它是否正确。我根据我在网上找到的示例实现了自己的 IProfileService,但随后将角色部分修改为:
if (_userManager.SupportsUserRole)
{
var roles = await _userManager.GetRolesAsync(user);
claims.AddRange(roles.Select(role => new Claim(JwtClaimTypes.Role, role)));
foreach (var item in roles)
{
var role = await _roleManager.FindByNameAsync(item);
if (!(role == null))
{
claims.AddRange(await _roleManager.GetClaimsAsync(role));
}
}
}
当它们被分配给角色时,默认实现似乎不包含声明,所以我的解决方案是遍历角色并获取声明并添加它们,这有效,我现在可以在我的 MVC 网站中使用它们.
我在不同的项目中有一个工作的 IdentityServer 和 MVC 客户端,我还在我的 asp.net 身份表中存储了针对角色的声明,这是我的种子数据代码,然后分配给用户:
if (await _roleManager.FindByNameAsync("Trainer") == null)
{
//Add Traininer Role
var trainerRole = new IdentityRole("Trainer");
await _roleManager.CreateAsync(trainerRole);
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.viewrelated"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.updatestatus"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "contacts.viewrelated"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "locations.viewrelated"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.delete"));
}
if (await _roleManager.FindByNameAsync("Booking Management") == null)
{
//Add Traininer Role
var trainerRole = new IdentityRole("Booking Management");
await _roleManager.CreateAsync(trainerRole);
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "companies.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "companies.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "companies.edit"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "companies.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "locations.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "locations.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "locations.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "locations.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "contacts.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "contacts.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "contacts.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "contacts.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.updatestatus"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.cancel"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "bookings.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "attendee.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "courses.view"));
}
if (await _roleManager.FindByNameAsync("Management") == null)
{
//Add Traininer Role
var trainerRole = new IdentityRole("Management");
await _roleManager.CreateAsync(trainerRole);
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "reporting.finance"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "reporting.customers"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "users.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "users.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "users.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "users.delete"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "config.view"));
}
if (await _roleManager.FindByNameAsync("Course Management") == null)
{
//Add Traininer Role
var trainerRole = new IdentityRole("Course Management");
await _roleManager.CreateAsync(trainerRole);
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "courses.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "courses.create"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "courses.update"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "courses.delete"));
}
if (await _roleManager.FindByNameAsync("Admin") == null)
{
//Add Traininer Role
var trainerRole = new IdentityRole("Admin");
await _roleManager.CreateAsync(trainerRole);
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "config.view"));
await _roleManager.AddClaimAsync(trainerRole, new Claim(CustomClaimTypes.Permission, "config.update"));
}
当我登录身份服务器时,我的权限是列表
当我使用我的 MVC 客户端登录时,我没有获得用户权限
在我的 MVC 客户端中,我希望能够在我的导航中执行类似的操作
@if (user.HasClaim(CustomClaimTypes.Permission, "config.view"))
{
<li>
<a href="#"><i class="fa fa-cogs"></i> <span class="nav-label" data-i18n="nav.layouts">Configuration Settings</span></a>
<ul class="nav nav-second-level collapse">
<li>
<a href="/configuration#!/awardingbodies/"> <span class="nav-label" data-i18n="nav.layouts">Awarding Bodies</span></a>
</li>
</ul>
</li>
}
理想情况下,我假设检查权限您不想不断查询数据库,所以我假设最好使用令牌获取权限,但我不知道该怎么做?
编辑 1:Identity Server 中客户端的配置 (Config.cs)
new Client
{
ClientId = "webclientmvc",
ClientName = "CRM MVC Client",
AllowedGrantTypes = GrantTypes.Hybrid,
AlwaysSendClientClaims = true,
RequireConsent = true,
ClientSecrets =
{
new Secret("secret".Sha256())
},
RedirectUris = { "http://localhost:5009/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:5009" },
AllowedScopes =
{
StandardScopes.OpenId.Name,
StandardScopes.Profile.Name,
StandardScopes.OfflineAccess.Name,
StandardScopes.Roles.Name,
StandardScopes.AllClaims.Name,
"api1",
"claims"
}
},
在 MVC 客户端中配置 (startup.cs)
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
AutomaticChallenge = true,
AutomaticAuthenticate = true,
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ClientId = "webclientmvc",
ClientSecret = "secret",
ResponseType = "code id_token",
Scope = { "profile", "api1", "offline_access", "roles" },
GetClaimsFromUserInfoEndpoint = true,
SaveTokens = true
});
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
我现在已经开始工作了,但想知道是否有人可以评论它是否正确。我根据我在网上找到的示例实现了自己的 IProfileService,但随后将角色部分修改为:
if (_userManager.SupportsUserRole)
{
var roles = await _userManager.GetRolesAsync(user);
claims.AddRange(roles.Select(role => new Claim(JwtClaimTypes.Role, role)));
foreach (var item in roles)
{
var role = await _roleManager.FindByNameAsync(item);
if (!(role == null))
{
claims.AddRange(await _roleManager.GetClaimsAsync(role));
}
}
}
当它们被分配给角色时,默认实现似乎不包含声明,所以我的解决方案是遍历角色并获取声明并添加它们,这有效,我现在可以在我的 MVC 网站中使用它们.