Angular
I am not sure if this is the correct way. I created my own IResourceOwnerPasswordValidator that extends AbpResourceOwnerPasswordValidator. I modified ValidateAsync to include my own rules and than called await base.ValidateAsync(context);
public override async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
await ReplaceEmailToUsernameOfInputIfNeeds(context).ConfigureAwait(false);
var user = _abUserManager.GetUser(context.UserName);
if (user != null)
{
var now = DateTime.Now;
if (user.ValidFromDate.CompareTo(now) > 0 || user.ValidToInclDate.AddDays(1).CompareTo(now) < 0)
{
_logger.LogInformation("User not in valid from and valid to dates : {username}", context.UserName);
await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "login not valid for dates", interactive: false)).ConfigureAwait(false);
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,"User Login not valid for current Date");
}
else if(!user.Active)
{
_logger.LogInformation("User is deactivated : {username}", context.UserName);
await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "is deactivated", interactive: false)).ConfigureAwait(false);
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "User is deactivated");
}
else
{
await base.ValidateAsync(context);
}
}
else
{
_logger.LogInformation("No user found matching username: {username}", context.UserName);
await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid username", interactive: false)).ConfigureAwait(false);
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
}
}
I also createe my own service to add users with the extra properties. I first create the user using the injected IAbUserManager and then update the user using the custom user respository
public override async Task<AbUserDto> CreateAsync(AbUserCreateDto input)
{
var user = _abUserManager.GetUser(input.Username);
if (user != null)
{
throw new BusinessException(AumErrorCodes.UserNameExists);
}
await ValidateInput(input.PhoneNumbers,input.PersonTypeId,input.CompanyId);
var emailAddress = input.EmailAddresses.First().EmailAddress;
var userId = await _abUserManager.CreateUserAsync(input.Username, input.Password, emailAddress,
input.ValidFromDate, input.ValidToInclDate, input.Active, input.DeactivationReason);
input.AbpUserId = userId;
return await base.CreateAsync(input);
}
Hi Alper
We are using the angular ui , not mvc. How would you do this on the angular ui?
According to https://github.com/abpframework/abp/issues/1082 this has been added to backlog with priority high, do you have an idea when this would be implemented?
I am using identity server and the ui is angular.
I have currently implemented this by extending the Volo.Abp.Identity.IdentityUser and updating GetRolesAsync,IsInRoleAsync and GetActiveRoles to filter only the active roles. I am not sure if this is the best way or not.
Hi
Thanks. I got it working.
Thank you for the quick response
I tried the work around. I changed the original code to the new code however I am still getting the same error. Original:
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<NexBaseDbContext>(options =>
{
/* Remove "includeAllEntities: true" to create
* default repositories only for aggregate roots */
options.AddDefaultRepositories(includeAllEntities: true);
});
Configure<AbpDbContextOptions>(options =>
{
/* The main point to change your DBMS.
* See also NexBaseMigrationsDbContextFactory for EF Core tooling. */
options.UseOracle();
});
}
New:
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<NexBaseDbContext>(options =>
{
/* Remove "includeAllEntities: true" to create
* default repositories only for aggregate roots */
options.AddDefaultRepositories(includeAllEntities: true);
});
Configure<AbpDbContextOptions>(options =>
{
/* The main point to change your DBMS.
* See also NexBaseMigrationsDbContextFactory for EF Core tooling. */
//options.UseOracle();
options.Configure(ctx => { ctx.DbContextOptions.UseOracle(ctx.ConnectionString); });
});
}
ading.Tasks.Task`1[Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Models.AbpLoginResult] Login(Volo.Abp.Account.Public.Web.Areas.Account.Controllers.Mod
els.UserLoginInfo) on controller Volo.Abp.Account.Public.Web.Areas.Account.Controllers.AccountController (Volo.Abp.Account.Pro.Public.Web).
[06:57:50 DBG] Login Url: /Account/Login
[06:57:50 DBG] Login Return Url Parameter: ReturnUrl
[06:57:50 DBG] Logout Url: /Account/Logout
[06:57:50 DBG] ConsentUrl Url: /Consent
[06:57:50 DBG] Consent Return Url Parameter: returnUrl
[06:57:50 DBG] Error Url: /Account/Error
[06:57:50 DBG] Error Id Parameter: errorId
[06:57:51 ERR] ---------- RemoteServiceErrorInfo ----------
{
"code": null,
"message": "An internal error occurred during your request!",
"details": null,
"data": {},
"validationErrors": null
}
[06:57:51 ERR] The specified transaction is not associated with the current connection. Only transactions associated with the current connection may be used.
System.InvalidOperationException: The specified transaction is not associated with the current connection. Only transactions associated with the current connec
tion may be used.
at Microsoft.EntityFrameworkCore.Storage.RelationalTransaction..ctor(IRelationalConnection connection, DbTransaction transaction, Guid transactionId, IDiagn
osticsLogger`1 logger, Boolean transactionOwned)
at Microsoft.EntityFrameworkCore.Storage.RelationalTransactionFactory.Create(IRelationalConnection connection, DbTransaction transaction, Guid transactionId
, IDiagnosticsLogger`1 logger, Boolean transactionOwned)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.CreateRelationalTransaction(DbTransaction transaction, Guid transactionId, Boolean transaction
Owned)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.UseTransactionAsync(DbTransaction transaction, Guid transactionId, CancellationToken cancellat
ionToken)
at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider`1.CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork)
at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider`1.CreateDbContextAsync(IUnitOfWork unitOfWork)
at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider`1.CreateDbContextAsync(IUnitOfWork unitOfWork, String connectionStringName, String connectio
nString)
at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider`1.GetDbContextAsync()
at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository`2.GetDbSetAsync()
at Volo.Abp.FeatureManagement.EntityFrameworkCore.EfCoreFeatureValueRepository.GetListAsync(String providerName, String providerKey)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`
3 proceed)
at Volo.Abp.FeatureManagement.FeatureManagementStore.SetCacheItemsAsync(String providerName, String providerKey, String currentName, FeatureValueCacheItem c
urrentCacheItem)
at Volo.Abp.FeatureManagement.FeatureManagementStore.GetCacheItemAsync(String name, String providerName, String providerKey)
at Volo.Abp.FeatureManagement.FeatureManagementStore.GetOrNullAsync(String name, String providerName, String providerKey)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`
3 proceed)
at Volo.Abp.Features.TenantFeatureValueProvider.GetOrNullAsync(FeatureDefinition feature)
at Volo.Abp.Features.FeatureChecker.GetOrNullValueFromProvidersAsync(IEnumerable`1 providers, FeatureDefinition feature)
at Volo.Abp.Features.FeatureChecker.GetOrNullAsync(String name)
at Volo.Abp.Features.FeatureCheckerBase.IsEnabledAsync(String name)
at Volo.Abp.Account.Public.Web.Ldap.LdapExternalLoginProvider.TryAuthenticateAsync(String userName, String plainPassword)
at Volo.Abp.Identity.AspNetCore.AbpSignInManager.PasswordSignInAsync(String userName, String password, Boolean isPersistent, Boolean lockoutOnFailure)
at Volo.Abp.Account.Public.Web.Areas.Account.Controllers.AccountController.Login(UserLoginInfo login)
at lambda_method1998(Closure , Object )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor e
xecutor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 ac at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor
executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 ac
tionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastT
ask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State ne
xt, Scope scope, Object state, Boolean isCompleted)
@alper. Thanks. I am getting the problem with a new solution in v4.2.1. My upgraded solution, I am getting the error on many other webapi services.
Debugging it, I get the error in this code in Microsoft.EntityFrameworkCore.Storage The connection.DbConnection and the transaction.Connection are not the same object.
when debugging there is only one connection defined, so it looks like somewhere in the transaction a new connection is opened
<br> <br>