ABP 权限拦截 第二篇

由于访问人数过多,我今天从新整理一下ABP权限认证机制,帮助大家更容易读懂

1、Abp 的权限拦截主要通过过滤器,    public class AbpAuthorizationFilter : IAsyncAuthorizationFilter, ITransientDependency 实现的,他的代码如下

    public class AbpAuthorizationFilter : IAsyncAuthorizationFilter, ITransientDependency
{
public ILogger Logger { get; set; } private readonly IAuthorizationHelper _authorizationHelper;
private readonly IErrorInfoBuilder _errorInfoBuilder;
private readonly IEventBus _eventBus; public AbpAuthorizationFilter(
IAuthorizationHelper authorizationHelper,
IErrorInfoBuilder errorInfoBuilder,
IEventBus eventBus)
{
_authorizationHelper = authorizationHelper;
_errorInfoBuilder = errorInfoBuilder;
_eventBus = eventBus;
Logger = NullLogger.Instance;
} public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
// Allow Anonymous skips all authorization
if (context.Filters.Any(item => item is IAllowAnonymousFilter))
{
return;
} if (!context.ActionDescriptor.IsControllerAction())
{
return;
} //TODO: Avoid using try/catch, use conditional checking
try
{
await _authorizationHelper.AuthorizeAsync(
context.ActionDescriptor.GetMethodInfo(),
context.ActionDescriptor.GetMethodInfo().DeclaringType
);
}
catch (AbpAuthorizationException ex)
{
Logger.Warn(ex.ToString(), ex); _eventBus.Trigger(this, new AbpHandledExceptionData(ex)); if (ActionResultHelper.IsObjectResult(context.ActionDescriptor.GetMethodInfo().ReturnType))
{
context.Result = new ObjectResult(new AjaxResponse(_errorInfoBuilder.BuildForException(ex), true))
{
StatusCode = context.HttpContext.User.Identity.IsAuthenticated
? (int) System.Net.HttpStatusCode.Forbidden
: (int) System.Net.HttpStatusCode.Unauthorized
};
}
else
{
context.Result = new ChallengeResult();
}
}
catch (Exception ex)
{
Logger.Error(ex.ToString(), ex); _eventBus.Trigger(this, new AbpHandledExceptionData(ex)); if (ActionResultHelper.IsObjectResult(context.ActionDescriptor.GetMethodInfo().ReturnType))
{
context.Result = new ObjectResult(new AjaxResponse(_errorInfoBuilder.BuildForException(ex)))
{
StatusCode = (int) System.Net.HttpStatusCode.InternalServerError
};
}
else
{
//TODO: How to return Error page?
context.Result = new StatusCodeResult((int)System.Net.HttpStatusCode.InternalServerError);
}
}
}
}

他的核心代码:

  await _authorizationHelper.AuthorizeAsync(
context.ActionDescriptor.GetMethodInfo(),
context.ActionDescriptor.GetMethodInfo().DeclaringType
);

要拦截异常处理,前提是类或者方法上面有AbpAuthorization 特性,我们来看看AbpAuthorization

   /// <summary>
/// This attribute is used on a method of an Application Service (A class that implements <see cref="IApplicationService"/>)
/// to make that method usable only by authorized users.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class AbpAuthorizeAttribute : Attribute, IAbpAuthorizeAttribute
{ /// <summary>
/// A list of permissions to authorize.
/// </summary>
public string[] Permissions { get; } /// <summary>
/// If this property is set to true, all of the <see cref="Permissions"/> must be granted.
/// If it's false, at least one of the <see cref="Permissions"/> must be granted.
/// Default: false.
/// </summary>
public bool RequireAllPermissions { get; set; } /// <summary>
/// Creates a new instance of <see cref="AbpAuthorizeAttribute"/> class.
/// </summary>
/// <param name="permissions">A list of permissions to authorize</param>
public AbpAuthorizeAttribute(params string[] permissions)
{
Permissions = permissions;
}
}

权限检查帮助类:AuthorizationHelper

    public class AuthorizationHelper : IAuthorizationHelper, ITransientDependency
{
public IAbpSession AbpSession { get; set; }
public IPermissionChecker PermissionChecker { get; set; }
public IFeatureChecker FeatureChecker { get; set; }
public ILocalizationManager LocalizationManager { get; set; } private readonly IFeatureChecker _featureChecker;
private readonly IAuthorizationConfiguration _authConfiguration; public AuthorizationHelper(IFeatureChecker featureChecker, IAuthorizationConfiguration authConfiguration)
{
_featureChecker = featureChecker;
_authConfiguration = authConfiguration;
AbpSession = NullAbpSession.Instance;
PermissionChecker = NullPermissionChecker.Instance;
LocalizationManager = NullLocalizationManager.Instance;
} //验证权限
public virtual async Task AuthorizeAsync(IEnumerable<IAbpAuthorizeAttribute> authorizeAttributes)
{
if (!_authConfiguration.IsEnabled)
{
return;
}
//判断当前用户是否登录
if (!AbpSession.UserId.HasValue)
{
//交给异常程序处理
throw new AbpAuthorizationException(
LocalizationManager.GetString(AbpConsts.LocalizationSourceName, "CurrentUserDidNotLoginToTheApplication")
);
} //检查所有权限
foreach (var authorizeAttribute in authorizeAttributes)
{
await PermissionChecker.AuthorizeAsync(authorizeAttribute.RequireAllPermissions, authorizeAttribute.Permissions);
}
} public virtual async Task AuthorizeAsync(MethodInfo methodInfo, Type type)
{
await CheckFeatures(methodInfo, type);
await CheckPermissions(methodInfo, type);
} protected virtual async Task CheckFeatures(MethodInfo methodInfo, Type type)
{
//检查必要特性
var featureAttributes = ReflectionHelper.GetAttributesOfMemberAndType<RequiresFeatureAttribute>(methodInfo, type); if (featureAttributes.Count <= )
{
return;
} foreach (var featureAttribute in featureAttributes)
{
await _featureChecker.CheckEnabledAsync(featureAttribute.RequiresAll, featureAttribute.Features);
}
} protected virtual async Task CheckPermissions(MethodInfo methodInfo, Type type)
{
//判断是否开启验证
if (!_authConfiguration.IsEnabled)
{
return;
} //是否有AllowAnonymous标记
if (AllowAnonymous(methodInfo, type))
{
return;
} //判断方法上面是否有AbpAuthorizeAttribute属性,没有就跳过
var authorizeAttributes =
ReflectionHelper
.GetAttributesOfMemberAndType(methodInfo, type)
.OfType<IAbpAuthorizeAttribute>()
.ToArray();
if (!authorizeAttributes.Any())
{
return;
}
//验证权限
await AuthorizeAsync(authorizeAttributes);
} private static bool AllowAnonymous(MemberInfo memberInfo, Type type)
{
return ReflectionHelper
.GetAttributesOfMemberAndType(memberInfo, type)
.OfType<IAbpAllowAnonymousAttribute>()
.Any();
}
}

权限检查主要通过这个类实现的,PermissionCheckerExtensions,他的核心方法        public static async Task AuthorizeAsync(this IPermissionChecker permissionChecker, bool requireAll, params string[] permissionNames)

PermissionCheckerExtensions 类的实现如下:

    public static class PermissionCheckerExtensions
{
/// <summary>
/// Checks if current user is granted for a permission.
/// </summary>
/// <param name="permissionChecker">Permission checker</param>
/// <param name="permissionName">Name of the permission</param>
public static bool IsGranted(this IPermissionChecker permissionChecker, string permissionName)
{
return AsyncHelper.RunSync(() => permissionChecker.IsGrantedAsync(permissionName));
} /// <summary>
/// Checks if a user is granted for a permission.
/// </summary>
/// <param name="permissionChecker">Permission checker</param>
/// <param name="user">User to check</param>
/// <param name="permissionName">Name of the permission</param>
public static bool IsGranted(this IPermissionChecker permissionChecker, UserIdentifier user, string permissionName)
{
return AsyncHelper.RunSync(() => permissionChecker.IsGrantedAsync(user, permissionName));
} /// <summary>
/// Checks if given user is granted for given permission.
/// </summary>
/// <param name="permissionChecker">Permission checker</param>
/// <param name="user">User</param>
/// <param name="requiresAll">True, to require all given permissions are granted. False, to require one or more.</param>
/// <param name="permissionNames">Name of the permissions</param>
public static bool IsGranted(this IPermissionChecker permissionChecker, UserIdentifier user, bool requiresAll, params string[] permissionNames)
{
return AsyncHelper.RunSync(() => IsGrantedAsync(permissionChecker, user, requiresAll, permissionNames));
} /// <summary>
/// Checks if given user is granted for given permission.
/// </summary>
/// <param name="permissionChecker">Permission checker</param>
/// <param name="user">User</param>
/// <param name="requiresAll">True, to require all given permissions are granted. False, to require one or more.</param>
/// <param name="permissionNames">Name of the permissions</param>
public static async Task<bool> IsGrantedAsync(this IPermissionChecker permissionChecker, UserIdentifier user, bool requiresAll, params string[] permissionNames)
{
if (permissionNames.IsNullOrEmpty())
{
return true;
} if (requiresAll)
{
foreach (var permissionName in permissionNames)
{
if (!(await permissionChecker.IsGrantedAsync(user, permissionName)))
{
return false;
}
} return true;
}
else
{
foreach (var permissionName in permissionNames)
{
if (await permissionChecker.IsGrantedAsync(user, permissionName))
{
return true;
}
} return false;
}
} /// <summary>
/// Checks if current user is granted for given permission.
/// </summary>
/// <param name="permissionChecker">Permission checker</param>
/// <param name="requiresAll">True, to require all given permissions are granted. False, to require one or more.</param>
/// <param name="permissionNames">Name of the permissions</param>
public static bool IsGranted(this IPermissionChecker permissionChecker, bool requiresAll, params string[] permissionNames)
{
return AsyncHelper.RunSync(() => IsGrantedAsync(permissionChecker, requiresAll, permissionNames));
} /// <summary>
/// Checks if current user is granted for given permission.
/// </summary>
/// <param name="permissionChecker">Permission checker</param>
/// <param name="requiresAll">True, to require all given permissions are granted. False, to require one or more.</param>
/// <param name="permissionNames">Name of the permissions</param>
public static async Task<bool> IsGrantedAsync(this IPermissionChecker permissionChecker, bool requiresAll, params string[] permissionNames)
{ //权限为空
if (permissionNames.IsNullOrEmpty())
{
return true;
} //检查所有权限
if (requiresAll)
{
foreach (var permissionName in permissionNames)
{
//检查权限
if (!(await permissionChecker.IsGrantedAsync(permissionName)))
{
return false;
}
} return true;
}
else
{
foreach (var permissionName in permissionNames)
{
if (await permissionChecker.IsGrantedAsync(permissionName))
{
return true;
}
} return false;
}
} /// <summary>
/// Authorizes current user for given permission or permissions,
/// throws <see cref="AbpAuthorizationException"/> if not authorized.
/// User it authorized if any of the <see cref="permissionNames"/> are granted.
/// </summary>
/// <param name="permissionChecker">Permission checker</param>
/// <param name="permissionNames">Name of the permissions to authorize</param>
/// <exception cref="AbpAuthorizationException">Throws authorization exception if</exception>
public static void Authorize(this IPermissionChecker permissionChecker, params string[] permissionNames)
{
Authorize(permissionChecker, false, permissionNames);
} /// <summary>
/// Authorizes current user for given permission or permissions,
/// throws <see cref="AbpAuthorizationException"/> if not authorized.
/// User it authorized if any of the <see cref="permissionNames"/> are granted.
/// </summary>
/// <param name="permissionChecker">Permission checker</param>
/// <param name="requireAll">
/// If this is set to true, all of the <see cref="permissionNames"/> must be granted.
/// If it's false, at least one of the <see cref="permissionNames"/> must be granted.
/// </param>
/// <param name="permissionNames">Name of the permissions to authorize</param>
/// <exception cref="AbpAuthorizationException">Throws authorization exception if</exception>
public static void Authorize(this IPermissionChecker permissionChecker, bool requireAll, params string[] permissionNames)
{
AsyncHelper.RunSync(() => AuthorizeAsync(permissionChecker, requireAll, permissionNames));
} /// <summary>
/// Authorizes current user for given permission or permissions,
/// throws <see cref="AbpAuthorizationException"/> if not authorized.
/// User it authorized if any of the <see cref="permissionNames"/> are granted.
/// </summary>
/// <param name="permissionChecker">Permission checker</param>
/// <param name="permissionNames">Name of the permissions to authorize</param>
/// <exception cref="AbpAuthorizationException">Throws authorization exception if</exception>
public static Task AuthorizeAsync(this IPermissionChecker permissionChecker, params string[] permissionNames)
{
return AuthorizeAsync(permissionChecker, false, permissionNames);
} /// <summary>
/// Authorizes current user for given permission or permissions,
/// throws <see cref="AbpAuthorizationException"/> if not authorized.
/// </summary>
/// <param name="permissionChecker">Permission checker</param>
/// <param name="requireAll">
/// If this is set to true, all of the <see cref="permissionNames"/> must be granted.
/// If it's false, at least one of the <see cref="permissionNames"/> must be granted.
/// </param>
/// <param name="permissionNames">Name of the permissions to authorize</param>
/// <exception cref="AbpAuthorizationException">Throws authorization exception if</exception>
public static async Task AuthorizeAsync(this IPermissionChecker permissionChecker, bool requireAll, params string[] permissionNames)
{
if (await IsGrantedAsync(permissionChecker, requireAll, permissionNames))
{
return;
} var localizedPermissionNames = LocalizePermissionNames(permissionChecker, permissionNames); if (requireAll)
{
throw new AbpAuthorizationException(
string.Format(
L(
permissionChecker,
"AllOfThesePermissionsMustBeGranted",
"Required permissions are not granted. All of these permissions must be granted: {0}"
),
string.Join(", ", localizedPermissionNames)
)
);
}
else
{
throw new AbpAuthorizationException(
string.Format(
L(
permissionChecker,
"AtLeastOneOfThesePermissionsMustBeGranted",
"Required permissions are not granted. At least one of these permissions must be granted: {0}"
),
string.Join(", ", localizedPermissionNames)
)
);
}
} public static string L(IPermissionChecker permissionChecker, string name, string defaultValue)
{
if (!(permissionChecker is IIocManagerAccessor))
{
return defaultValue;
} var iocManager = (permissionChecker as IIocManagerAccessor).IocManager;
using (var localizationManager = iocManager.ResolveAsDisposable<ILocalizationManager>())
{
return localizationManager.Object.GetString(AbpConsts.LocalizationSourceName, name);
}
} public static string[] LocalizePermissionNames(IPermissionChecker permissionChecker, string[] permissionNames)
{
if (!(permissionChecker is IIocManagerAccessor))
{
return permissionNames;
} var iocManager = (permissionChecker as IIocManagerAccessor).IocManager;
using (var localizationContext = iocManager.ResolveAsDisposable<ILocalizationContext>())
{
using (var permissionManager = iocManager.ResolveAsDisposable<IPermissionManager>())
{
return permissionNames.Select(permissionName =>
{
var permission = permissionManager.Object.GetPermissionOrNull(permissionName);
return permission?.DisplayName == null
? permissionName
: permission.DisplayName.Localize(localizationContext.Object);
}).ToArray();
}
}
}
}

以上大家会发现核心代码是  await _userManager.IsGrantedAsync(userId, permissionName);,这个类是在AbpUserManager,而这个类是用户管理的类,里面涉及的东西很多,比如Identity Server 4,我们只需要理解大概意思

    public class AbpUserManager<TRole, TUser> : UserManager<TUser>, IDomainService
where TRole : AbpRole<TUser>, new()
where TUser : AbpUser<TUser>
{
protected IUserPermissionStore<TUser> UserPermissionStore
{
get
{
if (!(Store is IUserPermissionStore<TUser>))
{
throw new AbpException("Store is not IUserPermissionStore");
} return Store as IUserPermissionStore<TUser>;
}
} public ILocalizationManager LocalizationManager { get; set; } protected string LocalizationSourceName { get; set; } public IAbpSession AbpSession { get; set; } public FeatureDependencyContext FeatureDependencyContext { get; set; } protected AbpRoleManager<TRole, TUser> RoleManager { get; } protected AbpUserStore<TRole, TUser> AbpUserStore { get; } public IMultiTenancyConfig MultiTenancy { get; set; } private readonly IPermissionManager _permissionManager;
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly ICacheManager _cacheManager;
private readonly IRepository<OrganizationUnit, long> _organizationUnitRepository;
private readonly IRepository<UserOrganizationUnit, long> _userOrganizationUnitRepository;
private readonly IOrganizationUnitSettings _organizationUnitSettings;
private readonly ISettingManager _settingManager;
private readonly IOptions<IdentityOptions> _optionsAccessor; public AbpUserManager(
AbpRoleManager<TRole, TUser> roleManager,
AbpUserStore<TRole, TUser> userStore,
IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<TUser> passwordHasher,
IEnumerable<IUserValidator<TUser>> userValidators,
IEnumerable<IPasswordValidator<TUser>> passwordValidators,
ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors,
IServiceProvider services,
ILogger<UserManager<TUser>> logger,
IPermissionManager permissionManager,
IUnitOfWorkManager unitOfWorkManager,
ICacheManager cacheManager,
IRepository<OrganizationUnit, long> organizationUnitRepository,
IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
IOrganizationUnitSettings organizationUnitSettings,
ISettingManager settingManager)
: base(
userStore,
optionsAccessor,
passwordHasher,
userValidators,
passwordValidators,
keyNormalizer,
errors,
services,
logger)
{
_permissionManager = permissionManager;
_unitOfWorkManager = unitOfWorkManager;
_cacheManager = cacheManager;
_organizationUnitRepository = organizationUnitRepository;
_userOrganizationUnitRepository = userOrganizationUnitRepository;
_organizationUnitSettings = organizationUnitSettings;
_settingManager = settingManager;
_optionsAccessor = optionsAccessor; AbpUserStore = userStore;
RoleManager = roleManager;
LocalizationManager = NullLocalizationManager.Instance;
LocalizationSourceName = AbpZeroConsts.LocalizationSourceName;
} public override async Task<IdentityResult> CreateAsync(TUser user)
{
var result = await CheckDuplicateUsernameOrEmailAddressAsync(user.Id, user.UserName, user.EmailAddress);
if (!result.Succeeded)
{
return result;
} var tenantId = GetCurrentTenantId();
if (tenantId.HasValue && !user.TenantId.HasValue)
{
user.TenantId = tenantId.Value;
} var isLockoutEnabled = user.IsLockoutEnabled; var identityResult = await base.CreateAsync(user);
if (identityResult.Succeeded)
{
await SetLockoutEnabledAsync(user, isLockoutEnabled);
} return identityResult;
} /// <summary>
/// Check whether a user is granted for a permission.
/// </summary>
/// <param name="userId">User id</param>
/// <param name="permissionName">Permission name</param>
public virtual async Task<bool> IsGrantedAsync(long userId, string permissionName)
{
return await IsGrantedAsync(
userId,
_permissionManager.GetPermission(permissionName)
);
} /// <summary>
/// Check whether a user is granted for a permission.
/// </summary>
/// <param name="user">User</param>
/// <param name="permission">Permission</param>
public virtual Task<bool> IsGrantedAsync(TUser user, Permission permission)
{
return IsGrantedAsync(user.Id, permission);
} /// <summary>
/// Check whether a user is granted for a permission.
/// </summary>
/// <param name="userId">User id</param>
/// <param name="permission">Permission</param>
public virtual async Task<bool> IsGrantedAsync(long userId, Permission permission)
{
//Check for multi-tenancy side,检查权限是否标记了多租户
if (!permission.MultiTenancySides.HasFlag(GetCurrentMultiTenancySide()))
{
return false;
} //Check for depended features
if (permission.FeatureDependency != null && GetCurrentMultiTenancySide() == MultiTenancySides.Tenant)
{
FeatureDependencyContext.TenantId = GetCurrentTenantId(); if (!await permission.FeatureDependency.IsSatisfiedAsync(FeatureDependencyContext))
{
return false;
}
} //Get cached user permissions
var cacheItem = await GetUserPermissionCacheItemAsync(userId);
if (cacheItem == null)
{
return false;
} //Check for user-specific value
if (cacheItem.GrantedPermissions.Contains(permission.Name))
{
return true;
} if (cacheItem.ProhibitedPermissions.Contains(permission.Name))
{
return false;
} //Check for roles
foreach (var roleId in cacheItem.RoleIds)
{
if (await RoleManager.IsGrantedAsync(roleId, permission))
{
return true;
}
} return false;
} /// <summary>
/// Gets granted permissions for a user.
/// </summary>
/// <param name="user">Role</param>
/// <returns>List of granted permissions</returns>
public virtual async Task<IReadOnlyList<Permission>> GetGrantedPermissionsAsync(TUser user)
{
var permissionList = new List<Permission>(); foreach (var permission in _permissionManager.GetAllPermissions())
{
if (await IsGrantedAsync(user.Id, permission))
{
permissionList.Add(permission);
}
} return permissionList;
} /// <summary>
/// Sets all granted permissions of a user at once.
/// Prohibits all other permissions.
/// </summary>
/// <param name="user">The user</param>
/// <param name="permissions">Permissions</param>
public virtual async Task SetGrantedPermissionsAsync(TUser user, IEnumerable<Permission> permissions)
{
var oldPermissions = await GetGrantedPermissionsAsync(user);
var newPermissions = permissions.ToArray(); foreach (var permission in oldPermissions.Where(p => !newPermissions.Contains(p)))
{
await ProhibitPermissionAsync(user, permission);
} foreach (var permission in newPermissions.Where(p => !oldPermissions.Contains(p)))
{
await GrantPermissionAsync(user, permission);
}
} /// <summary>
/// Prohibits all permissions for a user.
/// </summary>
/// <param name="user">User</param>
public async Task ProhibitAllPermissionsAsync(TUser user)
{
foreach (var permission in _permissionManager.GetAllPermissions())
{
await ProhibitPermissionAsync(user, permission);
}
} /// <summary>
/// Resets all permission settings for a user.
/// It removes all permission settings for the user.
/// User will have permissions according to his roles.
/// This method does not prohibit all permissions.
/// For that, use <see cref="ProhibitAllPermissionsAsync"/>.
/// </summary>
/// <param name="user">User</param>
public async Task ResetAllPermissionsAsync(TUser user)
{
await UserPermissionStore.RemoveAllPermissionSettingsAsync(user);
} /// <summary>
/// Grants a permission for a user if not already granted.
/// </summary>
/// <param name="user">User</param>
/// <param name="permission">Permission</param>
public virtual async Task GrantPermissionAsync(TUser user, Permission permission)
{
await UserPermissionStore.RemovePermissionAsync(user, new PermissionGrantInfo(permission.Name, false)); if (await IsGrantedAsync(user.Id, permission))
{
return;
} await UserPermissionStore.AddPermissionAsync(user, new PermissionGrantInfo(permission.Name, true));
} /// <summary>
/// Prohibits a permission for a user if it's granted.
/// </summary>
/// <param name="user">User</param>
/// <param name="permission">Permission</param>
public virtual async Task ProhibitPermissionAsync(TUser user, Permission permission)
{
await UserPermissionStore.RemovePermissionAsync(user, new PermissionGrantInfo(permission.Name, true)); if (!await IsGrantedAsync(user.Id, permission))
{
return;
} await UserPermissionStore.AddPermissionAsync(user, new PermissionGrantInfo(permission.Name, false));
} public virtual Task<TUser> FindByNameOrEmailAsync(string userNameOrEmailAddress)
{
return AbpUserStore.FindByNameOrEmailAsync(userNameOrEmailAddress);
} public virtual Task<List<TUser>> FindAllAsync(UserLoginInfo login)
{
return AbpUserStore.FindAllAsync(login);
} public virtual Task<TUser> FindAsync(int? tenantId, UserLoginInfo login)
{
return AbpUserStore.FindAsync(tenantId, login);
} public virtual Task<TUser> FindByNameOrEmailAsync(int? tenantId, string userNameOrEmailAddress)
{
return AbpUserStore.FindByNameOrEmailAsync(tenantId, userNameOrEmailAddress);
} /// <summary>
/// Gets a user by given id.
/// Throws exception if no user found with given id.
/// </summary>
/// <param name="userId">User id</param>
/// <returns>User</returns>
/// <exception cref="AbpException">Throws exception if no user found with given id</exception>
public virtual async Task<TUser> GetUserByIdAsync(long userId)
{
var user = await FindByIdAsync(userId.ToString());
if (user == null)
{
throw new AbpException("There is no user with id: " + userId);
} return user;
} public override async Task<IdentityResult> UpdateAsync(TUser user)
{
var result = await CheckDuplicateUsernameOrEmailAddressAsync(user.Id, user.UserName, user.EmailAddress);
if (!result.Succeeded)
{
return result;
} //Admin user's username can not be changed!
if (user.UserName != AbpUserBase.AdminUserName)
{
if ((await GetOldUserNameAsync(user.Id)) == AbpUserBase.AdminUserName)
{
throw new UserFriendlyException(string.Format(L("CanNotRenameAdminUser"), AbpUserBase.AdminUserName));
}
} return await base.UpdateAsync(user);
} public override async Task<IdentityResult> DeleteAsync(TUser user)
{
if (user.UserName == AbpUserBase.AdminUserName)
{
throw new UserFriendlyException(string.Format(L("CanNotDeleteAdminUser"), AbpUserBase.AdminUserName));
} return await base.DeleteAsync(user);
} public virtual async Task<IdentityResult> ChangePasswordAsync(TUser user, string newPassword)
{
var errors = new List<IdentityError>(); foreach (var validator in PasswordValidators)
{
var validationResult = await validator.ValidateAsync(this, user, newPassword);
if (!validationResult.Succeeded)
{
errors.AddRange(validationResult.Errors);
}
} if (errors.Any())
{
return IdentityResult.Failed(errors.ToArray());
} await AbpUserStore.SetPasswordHashAsync(user, PasswordHasher.HashPassword(user, newPassword));
return IdentityResult.Success;
} public virtual async Task<IdentityResult> CheckDuplicateUsernameOrEmailAddressAsync(long? expectedUserId, string userName, string emailAddress)
{
var user = (await FindByNameAsync(userName));
if (user != null && user.Id != expectedUserId)
{
throw new UserFriendlyException(string.Format(L("Identity.DuplicateUserName"), userName));
} user = (await FindByEmailAsync(emailAddress));
if (user != null && user.Id != expectedUserId)
{
throw new UserFriendlyException(string.Format(L("Identity.DuplicateEmail"), emailAddress));
} return IdentityResult.Success;
} public virtual async Task<IdentityResult> SetRoles(TUser user, string[] roleNames)
{
await AbpUserStore.UserRepository.EnsureCollectionLoadedAsync(user, u => u.Roles); //Remove from removed roles
foreach (var userRole in user.Roles.ToList())
{
var role = await RoleManager.FindByIdAsync(userRole.RoleId.ToString());
if (roleNames.All(roleName => role.Name != roleName))
{
var result = await RemoveFromRoleAsync(user, role.Name);
if (!result.Succeeded)
{
return result;
}
}
} //Add to added roles
foreach (var roleName in roleNames)
{
var role = await RoleManager.GetRoleByNameAsync(roleName);
if (user.Roles.All(ur => ur.RoleId != role.Id))
{
var result = await AddToRoleAsync(user, roleName);
if (!result.Succeeded)
{
return result;
}
}
} return IdentityResult.Success;
} public virtual async Task<bool> IsInOrganizationUnitAsync(long userId, long ouId)
{
return await IsInOrganizationUnitAsync(
await GetUserByIdAsync(userId),
await _organizationUnitRepository.GetAsync(ouId)
);
} public virtual async Task<bool> IsInOrganizationUnitAsync(TUser user, OrganizationUnit ou)
{
return await _userOrganizationUnitRepository.CountAsync(uou =>
uou.UserId == user.Id && uou.OrganizationUnitId == ou.Id
) > ;
} public virtual async Task AddToOrganizationUnitAsync(long userId, long ouId)
{
await AddToOrganizationUnitAsync(
await GetUserByIdAsync(userId),
await _organizationUnitRepository.GetAsync(ouId)
);
} public virtual async Task AddToOrganizationUnitAsync(TUser user, OrganizationUnit ou)
{
var currentOus = await GetOrganizationUnitsAsync(user); if (currentOus.Any(cou => cou.Id == ou.Id))
{
return;
} await CheckMaxUserOrganizationUnitMembershipCountAsync(user.TenantId, currentOus.Count + ); await _userOrganizationUnitRepository.InsertAsync(new UserOrganizationUnit(user.TenantId, user.Id, ou.Id));
} public virtual async Task RemoveFromOrganizationUnitAsync(long userId, long ouId)
{
await RemoveFromOrganizationUnitAsync(
await GetUserByIdAsync(userId),
await _organizationUnitRepository.GetAsync(ouId)
);
} public virtual async Task RemoveFromOrganizationUnitAsync(TUser user, OrganizationUnit ou)
{
await _userOrganizationUnitRepository.DeleteAsync(uou => uou.UserId == user.Id && uou.OrganizationUnitId == ou.Id);
} public virtual async Task SetOrganizationUnitsAsync(long userId, params long[] organizationUnitIds)
{
await SetOrganizationUnitsAsync(
await GetUserByIdAsync(userId),
organizationUnitIds
);
} private async Task CheckMaxUserOrganizationUnitMembershipCountAsync(int? tenantId, int requestedCount)
{
var maxCount = await _organizationUnitSettings.GetMaxUserMembershipCountAsync(tenantId);
if (requestedCount > maxCount)
{
throw new AbpException($"Can not set more than {maxCount} organization unit for a user!");
}
} public virtual async Task SetOrganizationUnitsAsync(TUser user, params long[] organizationUnitIds)
{
if (organizationUnitIds == null)
{
organizationUnitIds = new long[];
} await CheckMaxUserOrganizationUnitMembershipCountAsync(user.TenantId, organizationUnitIds.Length); var currentOus = await GetOrganizationUnitsAsync(user); //Remove from removed OUs
foreach (var currentOu in currentOus)
{
if (!organizationUnitIds.Contains(currentOu.Id))
{
await RemoveFromOrganizationUnitAsync(user, currentOu);
}
} //Add to added OUs
foreach (var organizationUnitId in organizationUnitIds)
{
if (currentOus.All(ou => ou.Id != organizationUnitId))
{
await AddToOrganizationUnitAsync(
user,
await _organizationUnitRepository.GetAsync(organizationUnitId)
);
}
}
} [UnitOfWork]
public virtual Task<List<OrganizationUnit>> GetOrganizationUnitsAsync(TUser user)
{
var query = from uou in _userOrganizationUnitRepository.GetAll()
join ou in _organizationUnitRepository.GetAll() on uou.OrganizationUnitId equals ou.Id
where uou.UserId == user.Id
select ou; return Task.FromResult(query.ToList());
} [UnitOfWork]
public virtual Task<List<TUser>> GetUsersInOrganizationUnit(OrganizationUnit organizationUnit, bool includeChildren = false)
{
if (!includeChildren)
{
var query = from uou in _userOrganizationUnitRepository.GetAll()
join user in Users on uou.UserId equals user.Id
where uou.OrganizationUnitId == organizationUnit.Id
select user; return Task.FromResult(query.ToList());
}
else
{
var query = from uou in _userOrganizationUnitRepository.GetAll()
join user in Users on uou.UserId equals user.Id
join ou in _organizationUnitRepository.GetAll() on uou.OrganizationUnitId equals ou.Id
where ou.Code.StartsWith(organizationUnit.Code)
select user; return Task.FromResult(query.ToList());
}
} public virtual async Task InitializeOptionsAsync(int? tenantId)
{
Options = JsonConvert.DeserializeObject<IdentityOptions>(_optionsAccessor.Value.ToJsonString()); //Lockout
Options.Lockout.AllowedForNewUsers = await IsTrueAsync(AbpZeroSettingNames.UserManagement.UserLockOut.IsEnabled, tenantId);
Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromSeconds(await GetSettingValueAsync<int>(AbpZeroSettingNames.UserManagement.UserLockOut.DefaultAccountLockoutSeconds, tenantId));
Options.Lockout.MaxFailedAccessAttempts = await GetSettingValueAsync<int>(AbpZeroSettingNames.UserManagement.UserLockOut.MaxFailedAccessAttemptsBeforeLockout, tenantId); //Password complexity
Options.Password.RequireDigit = await GetSettingValueAsync<bool>(AbpZeroSettingNames.UserManagement.PasswordComplexity.RequireDigit, tenantId);
Options.Password.RequireLowercase = await GetSettingValueAsync<bool>(AbpZeroSettingNames.UserManagement.PasswordComplexity.RequireLowercase, tenantId);
Options.Password.RequireNonAlphanumeric = await GetSettingValueAsync<bool>(AbpZeroSettingNames.UserManagement.PasswordComplexity.RequireNonAlphanumeric, tenantId);
Options.Password.RequireUppercase = await GetSettingValueAsync<bool>(AbpZeroSettingNames.UserManagement.PasswordComplexity.RequireUppercase, tenantId);
Options.Password.RequiredLength = await GetSettingValueAsync<int>(AbpZeroSettingNames.UserManagement.PasswordComplexity.RequiredLength, tenantId);
} protected virtual Task<string> GetOldUserNameAsync(long userId)
{
return AbpUserStore.GetUserNameFromDatabaseAsync(userId);
} private async Task<UserPermissionCacheItem> GetUserPermissionCacheItemAsync(long userId)
{
var cacheKey = userId + "@" + (GetCurrentTenantId() ?? );
return await _cacheManager.GetUserPermissionCache().GetAsync(cacheKey, async () =>
{
var user = await FindByIdAsync(userId.ToString());
if (user == null)
{
return null;
} var newCacheItem = new UserPermissionCacheItem(userId); foreach (var roleName in await GetRolesAsync(user))
{
newCacheItem.RoleIds.Add((await RoleManager.GetRoleByNameAsync(roleName)).Id);
} foreach (var permissionInfo in await UserPermissionStore.GetPermissionsAsync(userId))
{
if (permissionInfo.IsGranted)
{
newCacheItem.GrantedPermissions.Add(permissionInfo.Name);
}
else
{
newCacheItem.ProhibitedPermissions.Add(permissionInfo.Name);
}
} return newCacheItem;
});
} public override async Task<IList<string>> GetValidTwoFactorProvidersAsync(TUser user)
{
var providers = new List<string>(); foreach (var provider in await base.GetValidTwoFactorProvidersAsync(user))
{
if (provider == "Email" &&
!await IsTrueAsync(AbpZeroSettingNames.UserManagement.TwoFactorLogin.IsEmailProviderEnabled, user.TenantId))
{
continue;
} if (provider == "Phone" &&
!await IsTrueAsync(AbpZeroSettingNames.UserManagement.TwoFactorLogin.IsSmsProviderEnabled, user.TenantId))
{
continue;
} providers.Add(provider);
} return providers;
} private bool IsTrue(string settingName, int? tenantId)
{
return GetSettingValue<bool>(settingName, tenantId);
} private Task<bool> IsTrueAsync(string settingName, int? tenantId)
{
return GetSettingValueAsync<bool>(settingName, tenantId);
} private T GetSettingValue<T>(string settingName, int? tenantId) where T : struct
{
return tenantId == null
? _settingManager.GetSettingValueForApplication<T>(settingName)
: _settingManager.GetSettingValueForTenant<T>(settingName, tenantId.Value);
} private Task<T> GetSettingValueAsync<T>(string settingName, int? tenantId) where T : struct
{
return tenantId == null
? _settingManager.GetSettingValueForApplicationAsync<T>(settingName)
: _settingManager.GetSettingValueForTenantAsync<T>(settingName, tenantId.Value);
} protected virtual string L(string name)
{
return LocalizationManager.GetString(LocalizationSourceName, name);
} protected virtual string L(string name, CultureInfo cultureInfo)
{
return LocalizationManager.GetString(LocalizationSourceName, name, cultureInfo);
} private int? GetCurrentTenantId()
{
if (_unitOfWorkManager.Current != null)
{
return _unitOfWorkManager.Current.GetTenantId();
} return AbpSession.TenantId;
} private MultiTenancySides GetCurrentMultiTenancySide()
{
if (_unitOfWorkManager.Current != null)
{
return MultiTenancy.IsEnabled && !_unitOfWorkManager.Current.GetTenantId().HasValue
? MultiTenancySides.Host
: MultiTenancySides.Tenant;
} return AbpSession.MultiTenancySide;
} public virtual async Task AddTokenValidityKeyAsync(
TUser user,
string tokenValidityKey,
DateTime expireDate,
CancellationToken cancellationToken = default(CancellationToken))
{
await AbpUserStore.AddTokenValidityKeyAsync(user, tokenValidityKey, expireDate, cancellationToken);
} public virtual async Task<bool> IsTokenValidityKeyValidAsync(
TUser user,
string tokenValidityKey,
CancellationToken cancellationToken = default(CancellationToken))
{
return await AbpUserStore.IsTokenValidityKeyValidAsync(user, tokenValidityKey, cancellationToken);
} public virtual async Task RemoveTokenValidityKeyAsync(
TUser user,
string tokenValidityKey,
CancellationToken cancellationToken = default(CancellationToken))
{
await AbpUserStore.RemoveTokenValidityKeyAsync(user, tokenValidityKey, cancellationToken);
}
}
上一篇:【BZOJ4830】[HNOI2017]抛硬币(组合计数,拓展卢卡斯定理)


下一篇:bzoj 4830: [Hnoi2017]抛硬币 [范德蒙德卷积 扩展lucas]