ASP MVC 5 - 扩展身份 2.0
ASP MVC 5 - Extending Identity 2.0
我有以下 ApplicationUser
class,有没有办法添加声明或扩展身份,以便我可以通过执行以下操作检查用户是否在项目组中:User.Identity.IsInProjectGroup(1)
。
目前我必须继续进入数据库获取用户,然后调用 IsInProjectGroup
方法。
public class ApplicationUser : IdentityUser
{
public ApplicationUser()
{
Id = Guid.NewGuid().ToString();
Groups = new Collection<Group>();
}
public string FirstName { get; set; }
public ICollection<Group> Groups { get; set; }
public bool IsInProjectGroup(int projectId)
{
return Groups.Any(g => g.Projects.Select(x => x.Id).Contains(projectId));
}
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// how do you add claim???
userIdentity.AddClaim(new Claim("Group", ???));
return userIdentity;
}
}
有没有办法添加调用方法的声明,或者有其他方法可以实现这一点?
我正在考虑如下扩展,但不确定如何在我的 ApplicationUser
class 中添加这样的声明以及如何在下面的扩展方法中检查声明:
namespace App.Extensions
{
public static class IdentityExtensions
{
public static bool IsInProjectGroup(this IIdentity identity, int projectId)
{
// how would i do the check here???
}
}
}
这是一个简单的例子。
首先创建一个常量用作声明的键
public class Constants {
public class Security {
public class ClaimTypes
public const string ProjectGroups = "ProjectGroups";
}
}
}
然后您可以在创建身份时创建声明
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) {
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// how do you add claim???
if(Groups.Any()) { //assuming this is a navigation property
//create a claim type/name/key
//replace with you desired key. Store in a constant for later use
var claimName = Constants.Security.ClaimTypes.ProjectGroup;
//create claims from current groups.
var claims = Groups.SelectMany(g => g.Projects.Select(x => x.Id))
.Select(id => new System.Security.Claims.Claim(claimName, id.ToString()));
userIdentity.AddClaims(claims);
}
return userIdentity;
}
对于检索,您可以创建自己的扩展方法来检查声明本身内的组,而不是访问数据库。
public static class IdentityExtensions {
public static bool IsInProjectGroup(this IIdentity identity, int projectId) {
// how would i do the check here???
if(identity != null) {
var claimsIdentity = identity as ClaimsIdentity;
if (claimsIdentity != null) {
return claimsIdentity
.FindAll(Constants.Security.ClaimTypes.ProjectGroups)
.Any(claim => claim.Value == projectId.ToString());
}
}
return false;
}
}
我有以下 ApplicationUser
class,有没有办法添加声明或扩展身份,以便我可以通过执行以下操作检查用户是否在项目组中:User.Identity.IsInProjectGroup(1)
。
目前我必须继续进入数据库获取用户,然后调用 IsInProjectGroup
方法。
public class ApplicationUser : IdentityUser
{
public ApplicationUser()
{
Id = Guid.NewGuid().ToString();
Groups = new Collection<Group>();
}
public string FirstName { get; set; }
public ICollection<Group> Groups { get; set; }
public bool IsInProjectGroup(int projectId)
{
return Groups.Any(g => g.Projects.Select(x => x.Id).Contains(projectId));
}
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// how do you add claim???
userIdentity.AddClaim(new Claim("Group", ???));
return userIdentity;
}
}
有没有办法添加调用方法的声明,或者有其他方法可以实现这一点?
我正在考虑如下扩展,但不确定如何在我的 ApplicationUser
class 中添加这样的声明以及如何在下面的扩展方法中检查声明:
namespace App.Extensions
{
public static class IdentityExtensions
{
public static bool IsInProjectGroup(this IIdentity identity, int projectId)
{
// how would i do the check here???
}
}
}
这是一个简单的例子。
首先创建一个常量用作声明的键
public class Constants {
public class Security {
public class ClaimTypes
public const string ProjectGroups = "ProjectGroups";
}
}
}
然后您可以在创建身份时创建声明
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) {
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// how do you add claim???
if(Groups.Any()) { //assuming this is a navigation property
//create a claim type/name/key
//replace with you desired key. Store in a constant for later use
var claimName = Constants.Security.ClaimTypes.ProjectGroup;
//create claims from current groups.
var claims = Groups.SelectMany(g => g.Projects.Select(x => x.Id))
.Select(id => new System.Security.Claims.Claim(claimName, id.ToString()));
userIdentity.AddClaims(claims);
}
return userIdentity;
}
对于检索,您可以创建自己的扩展方法来检查声明本身内的组,而不是访问数据库。
public static class IdentityExtensions {
public static bool IsInProjectGroup(this IIdentity identity, int projectId) {
// how would i do the check here???
if(identity != null) {
var claimsIdentity = identity as ClaimsIdentity;
if (claimsIdentity != null) {
return claimsIdentity
.FindAll(Constants.Security.ClaimTypes.ProjectGroups)
.Any(claim => claim.Value == projectId.ToString());
}
}
return false;
}
}