Hi liangshiwei,
Try
I tried this but this is not working, Can we connect once ?
var users = (await _roleRepository.GetDbSetAsync()).Where(x => EF.Property<int>(x, "PropertyAdded") == 1).ToListAsync();
Below code is working for user. In same way I want to do it for role. But there is no class like AppRoles, help me with this as well
public async Task<bool> MakeUserInactiveOnDormacyDaysCompletionAsync(Guid userId)
{
try
{
var user = await _appUserRepository.GetAsync(userId);
if (user != null)
{
user.Status = AbpUserStatusEnum.InActive;
await _appUserRepository.UpdateAsync(user);
}
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
Hi,
I have already implemented it in seperate identity project
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(AbpSignInManager), typeof(SignInManager<Volo.Abp.Identity.IdentityUser>))]
public class LitmusSiginManager : AbpSignInManager
{
private readonly IRepository<AppUser, Guid> _appUserRepository;
public LitmusSiginManager(IdentityUserManager userManager,
IHttpContextAccessor contextAccessor,
IUserClaimsPrincipalFactory<Volo.Abp.Identity.IdentityUser> claimsFactory,
IOptions<IdentityOptions> optionsAccessor,
ILogger<SignInManager<Volo.Abp.Identity.IdentityUser>> logger,
IAuthenticationSchemeProvider schemes,
IUserConfirmation<Volo.Abp.Identity.IdentityUser> confirmation,
IOptions<AbpIdentityOptions> options,
IRepository<AppUser, Guid> appUserRepository
) : base(userManager,
contextAccessor,
claimsFactory,
optionsAccessor,
logger,
schemes,
confirmation,
options)
{
_appUserRepository = appUserRepository;
}
public override async Task<SignInResult> PasswordSignInAsync(Volo.Abp.Identity.IdentityUser user, string password, bool isPersistent, bool lockoutOnFailure)
{
var appUser = await _appUserRepository.FirstOrDefaultAsync(x => x.Id == user.Id);
if (appUser != null)
{
if (appUser.Status == AbpUserStatusEnum.InActive)
throw new AbpAuthorizationException("User is in InActive state.");
}
return base.PasswordSignInAsync(user, password, isPersistent, lockoutOnFailure).Result;
}
}
Actually I need to work when I log in from angular. I tried as per you gif to login via https://localhost:44350/Account/Login But I am getting this error :
"Status" is the extra column I added to AbpUsers table : reference https://support.abp.io/QA/Questions/1826/Customizing-Application-Modules-Extending-User-Entity-ie-ApbUsers When I do this same logic in some application layer it works fine. I don't understand why I am getting this error here
Note : My debugger was not hit for method PasswordSignInAsync()
typeof(SignInManager<IdentityUser>)
Hi, Even with this its not working
Hi EngincanV,
I implemented custom signInManager, I registered it in PreConfigureServices as well but its not working. PasswordSignInAsync : My debugger doesn't even hit this method. And user was able to login.
Not sure where it went wrong.
My Code :
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(AbpSignInManager))]
public class LitmusSiginManager : AbpSignInManager
{
private readonly IRepository<AppUser, Guid> _appUserRepository;
public LitmusSiginManager(IdentityUserManager userManager,
IHttpContextAccessor contextAccessor,
IUserClaimsPrincipalFactory<Volo.Abp.Identity.IdentityUser> claimsFactory,
IOptions<IdentityOptions> optionsAccessor,
ILogger<SignInManager<Volo.Abp.Identity.IdentityUser>> logger,
IAuthenticationSchemeProvider schemes,
IUserConfirmation<Volo.Abp.Identity.IdentityUser> confirmation,
IOptions<AbpIdentityOptions> options,
IRepository<AppUser, Guid> appUserRepository
) : base(userManager,
contextAccessor,
claimsFactory,
optionsAccessor,
logger,
schemes,
confirmation,
options)
{
_appUserRepository = appUserRepository;
}
public override async Task<SignInResult> PasswordSignInAsync(Volo.Abp.Identity.IdentityUser user, string password, bool isPersistent, bool lockoutOnFailure)
{
var appUser = await _appUserRepository.FirstOrDefaultAsync(x => x.Id == user.Id);
if (appUser != null)
{
if (appUser.Status == AbpUserStatusEnum.InActive)
throw new AbpAuthorizationException("User is in InActive state.");
}
return base.PasswordSignInAsync(user, password, isPersistent, lockoutOnFailure).Result;
}
}
IdentityServerModule :
public class LitmusIdentityServerModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<IdentityBuilder>(identityBuilder =>
{
identityBuilder.AddSignInManager<LitmusSiginManager>();
});
}
}
Can you tell me what is wrong ?
You can examine this document to see how you can create a CustomSigninManager.
And after you've created CustomSigninManager, you can override the SignInAsync method and implement your logic.
Don't forget to register your CustomSigninManager => https://docs.abp.io/en/abp/2.9/How-To/Customize-SignIn-Manager#register-to-dependency-injection
But this is for v2.9 right ? My project is on v4.3.1 And on gitHub as well I was not able to find SignInManager code, If u can provide github source code for SignInManager it will be helpful.
I want to perform some check for the user before loggin in. If user pass those check user should be able to login or else throw some validation error.
What is the better approach for this requirement ?
I tried implementing IUserValidator but its not working as per expected.
There is already another ticket going on with 2 different topic so creating this ticket for this topic https://support.abp.io/QA/Questions/1826/Customizing-Application-Modules-Extending-User-Entity-ie-ApbUsers#answer-3ac227f1-8d97-2c1e-25c5-39fef082cb09
Getting error : The property 'IdentityUser.IsActive' could not be found. Ensure that the property exists and has been included in the model.
See https://docs.abp.io/en/abp/latest/Entity-Framework-Core#mapefcoreproperty
Steps Which I followed
#1 EntityFrameworkCore project : LitmusEfCoreEntityExtensionMappings
public static class LitmusEfCoreEntityExtensionMappings
{
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
public static void Configure()
{
OneTimeRunner.Run(() =>
{
ObjectExtensionManager.Instance
.MapEfCoreProperty<IdentityUser, bool>(
"IsActive",
(entityBuilder, propertyBuilder) =>
{
propertyBuilder.HasDefaultValue(true);
}
);
ObjectExtensionManager.Instance
.MapEfCoreProperty<IdentityRole, RoleType>("RoleType");
});
}
}
I took reference of the same URL.
My debugger didn't even hit this LitmusUserValidator ValidateAsync method while logging in
Try Put to
PreConfigureServices
Not working doing this as well.
May be we can connect and you can check personally.
Hi
I tried using https://docs.abp.io/en/abp/latest/Object-Extensions#setproperty for "PropertyAdded" i.e. IsActive
By using below code
public async Task<bool> MakeUserInactive(string userId)
{
var user = await _identityUserManager.FindByIdAsync(userId);
var context = await _userRepository.GetDbContextAsync();
context.Entry<Volo.Abp.Identity.IdentityUser>(user).Property("IsActive").CurrentValue = false;
await CurrentUnitOfWork.SaveChangesAsync();
return true;
}
Getting error : The property 'IdentityUser.IsActive' could not be found. Ensure that the property exists and has been included in the model.
And By using below code :
public async Task<bool> MakeUserInactive(string userId)
{
var user = await _identityUserManager.FindByIdAsync(userId);
user.SetProperty("IsActive", false);
return true;
}
IsActive is set in ExtraProperties but the column value of IsActive remains true.
#2 My Validator class :
public class LitmusUserValidator<TUser> : IUserValidator<TUser> where TUser : Volo.Abp.Identity.IdentityUser
{
private readonly IIdentityUserRepository _userRepository;
public LitmusUserValidator(IIdentityUserRepository userRepository)
{
_userRepository = userRepository;
}
public async Task<IdentityResult> ValidateAsync(UserManager<TUser> manager, TUser user)
{
var errors = new List<IdentityError>();
var users = (await _userRepository.GetDbSetAsync())
.Where(x => EF.Property<bool>(x, "IsActive") == false
&& EF.Property<Guid>(x, "Id") == user.Id)
.ToListAsync();
//Used list in above code because I am not able to access "IsActive" i.e. Custom property added on single object.
if(users.Result.Count != 0)
{
errors.Add(new IdentityError
{
Description = "User with InActive status cannot login"
});
}
return errors.Any()
? IdentityResult.Failed(errors.ToArray())
: IdentityResult.Success;
}
}
LitmusIdentityServerModule : My debugger didn't even hit this LitmusUserValidator ValidateAsync method while logging in I was able to login with user having "IsActive" == false;
public override void ConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<IdentityBuilder>(options => {
options.AddUserValidator<LitmusUserValidator<Volo.Abp.Identity.IdentityUser>>();
});
}
- Use EF Core API
see : https://docs.abp.io/en/abp/latest/Entity-Framework-Core#access-to-the-ef-core-api
var users = (await _userRepository.GetDbSetAsync()).Where(x => EF.Property<int>(x, "PropertyAdded") == 1).ToListAsync();
Is there a way where I find one item of this list and want to update its "PropertyAdded" column. How do I do this ?
You can use the
IUserValidator
See https://github.com/abpframework/abp/issues/3990
Is there any abp.io document where implementation of UserValidator class is provided ? Can you provide me sample of this class ? And how can I find my custom column here ?
In the below code there is one option called options.SignIn.RequireConfirmedEmail
If I would able to find my added column here I think it will resolve my issue.
IdentityServerModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
Configure<IdentityOptions>(options =>
{
options.User.AllowedUserNameCharacters = null;
//options.SignIn.RequireConfirmedEmail <-- talking about this above
});
}