grandchamp / identity.dapper Goto Github PK
View Code? Open in Web Editor NEWIdentity package that uses Dapper instead EntityFramework for use with .NET Core
License: MIT License
Identity package that uses Dapper instead EntityFramework for use with .NET Core
License: MIT License
I just managed to setup external login with Google. Ran into a few issues:
public static string SelectFilterWithTableName(this IEnumerable<string> propertyNames, string tableName)
{
var propertyNamesArray = propertyNames.ToArray();
var filterBuilderArray = new List<string>(propertyNamesArray.Length);
for (int i = 0; i < propertyNamesArray.Length; i++)
The line below added " to propertynames, allthough the propertyNamesArray already contained "propertyName". Deleting them here fixed it for me, I dont know if it really should be changed somewhere else instead?
filterBuilderArray.Add($"\"{tableName}\".{propertyNamesArray[i]}");
return string.Join(", ", filterBuilderArray);
}
The file /src/Identity.Dapper.SqlServer/Models/SqlServerConfiguration.cs
GetUserLoginByLoginProviderAndProviderKeyQuery = "SELECT TOP 1 %USERFILTER% FROM %SCHEMA%.%USERTABLE%, %SCHEMA%.%USERLOGINTABLE% WHERE LoginProvider = %LOGINPROVIDER% AND ProviderKey = %PROVIDERKEY%";
So I changed it to
GetUserLoginByLoginProviderAndProviderKeyQuery = "SELECT TOP 1 %USERFILTER% FROM %SCHEMA%.%USERTABLE%, %SCHEMA%.%USERLOGINTABLE% WHERE %SCHEMA%.%USERTABLE%.Id = %SCHEMA%.%USERLOGINTABLE%.UserId AND LoginProvider = %LOGINPROVIDER% AND ProviderKey = %PROVIDERKEY%"; to get it working.
Don't have the skillz to make changes and PR, so hoping someone else will. Sorry :)
Steps to replicate:
Login user via external provider and then grab user information.
var info = await _signInManager.GetExternalLoginInfoAsync();
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, false);
var user = await _userManager.FindByLoginAsync(info.LoginProvider, info.ProviderKey);
The user object does not have its Id or any of the fields filled in. The login succeeds and the UserName field gets populated, but nothing else. Is this a bug or intended? If intended why is that so, is it possible to get it to fill out other information such as UserId?
For my project I created extension models for each of the Identity.Dapper.Entities classes so that I can customize the various models. However, when I then extended the stores and repos I run into problems because the stores and repos are based on the DapperIdentityUser<int>
and DapperIdentityRole<int>
classes, not the DapperIdentityUser<TKey, TUserClaim, TUserRole, TUserLogin>
and DapperIdentityRole<TKey, TUserRole, TRoleClaim>
classes.
Ex:
public class User : DapperIdentityUser<int, UserClaim, UserRole, UserLogin>
{
}
public class UserRepository : UserRepository<User, int, UserRole, RoleClaim>, IUserRepository
{
private readonly IConnectionProvider _connectionProvider;
private readonly ILogger<UserRepository> _log;
private readonly SqlConfiguration _sqlConfiguration;
private readonly IRoleRepository _roleRepository;
//private readonly IRoleRepository<DapperIdentityRole<int>, int, UserRole, RoleClaim> _roleRepository;
public UserRepository(IConnectionProvider connProv,
ILogger<UserRepository> log,
SqlConfiguration sqlConf,
//IRoleRepository<DapperIdentityRole<int>, int, UserRole, RoleClaim> roleRepo
IRoleRepository roleRepo
)
: base(connProv, log, sqlConf, roleRepo)
{
_connectionProvider = connProv;
_log = log;
_sqlConfiguration = sqlConf;
_roleRepository = roleRepo;
}
// more methods here
}
This cannot compile because
namespace Identity.Dapper.Repositories
{
public class UserRepository<TUser, TKey, TUserRole, TRoleClaim> : IUserRepository<TUser, TKey, TUserRole, TRoleClaim>
where TUser : DapperIdentityUser<TKey>
where TKey : IEquatable<TKey>
where TUserRole : DapperIdentityUserRole<TKey>
where TRoleClaim : DapperIdentityRoleClaim<TKey>
//....
}
here we are expecting TUser : DapperIdentityUser<TKey>
but TUser : DapperIdentityUser<int, UserClaim, UserRole, UserLogin>
, an ancestor.
Can the repos and stores be altered to use the more general User and Role classes?
Hi! Is it possible to assign claims to the roles? So when user logs in, all the claims of his roles are automatically attached to a user. (I want to have permission claims.)
I get the 'NotSupportedException: Store does not implement IRoleClaimStore' exception when try to execute next line of code:
this.roleManager.AddClaimAsync(role, new Claim("Permission", permissionName))
Also as I can see there are no tables in the database to store claim-role relations.
Thank you for help!
Hello,
Thank you very much for your great job, i am not currently used it, but i will soon. I am developing a .net core api 1.1 app and i use Dapper with a mysql connector instead of Entity Framework. I search for 4 days for a similar project. What is not ready yet to use it?
I am having an issue with roles.
When I retrieve a user that has roles assigned by doing:
var user = await _userManager.FindByEmailAsync(model.Email);
The roles collection is returned empty. The same occur w/ FindByIdAsync
& FindByNameAsync
Thanks for your work on this library.
Add support for MySQL.
When i try to get all Users from Usermanger i get an
An exception of type 'System.NotImplementedException' occurred in Identity.Dapper.dll but was not handled in user code: 'The method or operation is not implemented.'
at Identity.Dapper.Stores.DapperUserStore`7.get_Users()
exception.
var result = UserManager.Users.ToList();
hi,
first evrything works very well. Thanks for your work. But if i register a new user, the email is stored in uppercase in the mysql database. it´s a litte bit irritating, if you want to show the email at your spa (or other homepage) and it´s in upperacse.
So my questioin is:
is it only a problem by me or is it "normal" and wanted by you. At the mysql code for the database, i can´t find something that the email should stored in uppercase.
Thanks for your help.
When you update your project to the latest libraries, you will find that Environment.OSVersion is now deprecated. This project seems to use it in QueryList class.
var platform = Environment.OSVersion.Platform.ToString();
If someone is interested in making a simple logo for the project, will be welcome.
Make API compatible with .NET Core RTM.
Identity.Dapper should support ConnectionString configuration out of the box. Chances are the project will require a connection to a DB and will use the standard ConnectionString settings. Identity.Dapper should simply re-use that be default instead of having their own ConnectionProvider.
Identity.Dapper connection information requires that the username and password be added as separate JSON fields in the settings files, while normally the credentials are within the ConnectionString itself as we can see:
https://www.connectionstrings.com/postgresql/
and
https://docs.microsoft.com/en-us/azure/postgresql/connect-csharp
string connString = String.Format( "Server={0}; User Id={1}; Database={2}; Port={3}; Password={4};", Host, User, DBname, Port, Password);
This will allow us to have one ConnectionString for our app and Identity
Cover entire project with unit tests.
Hello guys,
I'm new to the .Net world so I might have missed something,
Can we discuss the choice of "dbo" as a default schema for postgres?
Shouldn't it be "public" instead as it is afaik the most common schema used for pgsql?
Maybe it would be nice to have the opportunity to change it in any way, Sorry for the inconvenience if this is already possible but didn't found the way to do it.
Add PostgreSQL implementation
Hi, I want to use JWT token and refresh token. I didn't figure out how to use.Do you know how can I implement token in .net core 2.0 using this package?
Hi, I noticed that you don't wrap your table names with [ ]. By that I mean if you query on [dbo].User you will get an error because User is a reserved keyword. However if you query [dbo].[User] then it will work. In any case, I would suggest updating the scripts in the respective projects to wrap those and thus allow people to name their tables however they want without having to change your code too much.
I know you don't have that problem now because you prefixed your table names with Identity, but if I wanted to change those names to my custom names then I will basically rewrite your adapter dlls, but it would be nice not to have to rewrite too much code to make it work and only have to update the variable names where your tables are stored.
the project as I downloaded it, works fine. But I needed to customize it a bit.
I took the project here, and incorporated it into a new .net Core 2.1 project. In the process, I somehow broke it. The part I broke is related to dependency injection, and I'm not seeing the issue.
In my Startup.CS,
services.ConfigureDapperConnectionProvider<SqlServerConnectionProvider>(Configuration.GetSection("DapperIdentity")) .ConfigureDapperIdentityCryptography(Configuration.GetSection("DapperIdentityCryptography")) .ConfigureDapperIdentityOptions(new DapperIdentityOptions { UseTransactionalBehavior = false });
I'm debugging it, and when I get to the code below, the _connectionProviderOptions is null. On the sample project provided, it works fine. As far as I can tell, both projects are identical, so I can't see what I broke. The one difference is that the provided project SDK is NetStandard.Library (2.0.3), and my project SDK is Microsoft.NetCore.App (2.1). So that does pull in different versions of the dependent libraries. I suspect that is why it's broken. Where I am confused, is that when I put the dependency in, I put it in as SqlServerConnectionProvider. When it's refenced below, it's referenced as ConnectionProviderOptions. Granted, I'm new to dependency injection, but to me, that should be null, because they are different types. But in the app provided, it does somehow convert them.
`namespace Identity.Dapper.SqlServer.Connections
{
public class SqlServerConnectionProvider : IConnectionProvider
{
private readonly IOptions _connectionProviderOptions;
private readonly EncryptionHelper _encryptionHelper;
public SqlServerConnectionProvider(IOptions connProvOpts, EncryptionHelper encHelper)
{
_connectionProviderOptions = connProvOpts;
_encryptionHelper = encHelper;
}
public DbConnection Create()
{
if (_connectionProviderOptions.Value == null)
throw new ArgumentNullException("There's no DapperIdentity configuration section registered. Please, register the section in appsettings.json or user secrets.");
`
Hi guys nice work.
I have found one inconsistency regarding the claim objects. In the System.Security.Claims there is a constructor you are using:
//
// Summary:
// Initializes a new instance of the System.Security.Claims.Claim class with the
// specified claim type, and value.
//
// Parameters:
// type:
// The claim type.
//
// value:
// The claim value.
//
// Exceptions:
// T:System.ArgumentNullException:
// type or value is null.
public Claim(string type, string value);
As you can see if one of the input values is null then an exception is thrown.
In the MSSQL defintion for the table IdentityUserClaim the value is NULL, and therefore unaware dev will get the exception being thrown as soon as he tries to sign in:
CREATE TABLE [IdentityUserClaim](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] NOT NULL,
[ClaimType] [varchar](256) NOT NULL,
**[ClaimValue] [varchar](256) NULL,**
CONSTRAINT [PK_IdentityUserClaim] PRIMARY KEY CLUSTERED
Hi,
AddDapperIdentityForSqlServer() is not working in .net core 2.0. I'm getting this error
Reference to type 'IdentityBuilder' claims it is defined in 'Microsoft.AspNetCore.Identity', but it could not be found.I updated my project to .net core 2.0 and now having problem with AddDapperIdentityForSqlServer is not available in Startup.cs. Do you know how can I fix this?
Oracle implementation.
At the sample web Implementation you add at the CustomUser the filed address. Is it right that a column address is automatically creates at the database? I need some more column at the MysQl database and i´m not sure if i add the columns per hand in that MySql file: https://github.com/grandchamp/Identity.Dapper/blob/master/IdentityTablesMySql.sql or if your code does it for me.
p.s:
but I get an error if i try to implement the IdentityTablesMySql.sql at my MySql server (which is outside of my Identity project). I get the error message: ERROR 1215 (HY000) at line 10: Cannot add foreign key constraint
Thanks for answer
On Identity.Dapper.SqlServer\Extensions\ServiceCollectionExtensions.cs there is an commented implementation with generics in AddStores that i can't make work.
I always get DI activation exception.
I am experiencing an exception on TryDecryptAES256.
Please see the following PR for more info: #66
I believe there is an issue when the primary key is a GUID.
The issue is probably on line 260 in the DapperUserStore
var result = await _userRepository.GetByIdAsync((TKey)Convert.ChangeType(userId, typeof(TKey)));
this could maybe be an alternative:
T t = (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(text);
Since much of the problems are related to raw queries, i think the best way to test is creating a integration tests project.
I'll start working on .NET Core 2.0 branch.
Hello. I want to use guid ids for my app and i created CustomUser and CustomRole as
public class CustomUser : DapperIdentityUser<Guid>
{
}
public class CustomRole : DapperIdentityRole<Guid>
{
}
set Identity in Startup.cs
services.AddIdentity<CustomUser, CustomRole>(x =>
{
x.Password.RequireDigit = false;
x.Password.RequiredLength = 1;
x.Password.RequireLowercase = false;
x.Password.RequireNonAlphanumeric = false;
x.Password.RequireUppercase = false;
})
.AddDapperIdentityFor<PostgreSqlConfiguration, Guid>()
.AddDefaultTokenProviders();
but i get exception while dependecies resolve in my AccountController.cs
private readonly UserManager<CustomUser> _userManager;
private readonly SignInManager<CustomUser> _signInManager;
public AccountController(UserManager<CustomUser> userManager, SignInManager<CustomUser> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}
Raw exception
System.InvalidOperationException: Unable to resolve service for type 'Identity.Dapper.Factories.Contracts.IQueryFactory' while attempting to activate 'Identity.Dapper.Repositories.RoleRepository
4[Trytoremember.Core.Entities.CustomRole,System.Guid,Identity.Dapper.Entities.DapperIdentityUserRole1[System.Guid],Identity.Dapper.Entities.DapperIdentityRoleClaim
1[System.Guid]]'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, ISet1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, ISet
1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, ISet1 callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, ISet
1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, ISet1 callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, ISet
1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, ISet1 callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, ISet
1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, ISet1 callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, ISet
1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, ISet1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, ISet
1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, ISet1 callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, ISet
1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, ISet1 callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, ISet
1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(Type serviceType, Type implementationType, ISet1 callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, ISet
1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, ISet1 callSiteChain) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, ISet
1 callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType, ServiceProvider serviceProvider)
at System.Collections.Concurrent.ConcurrentDictionaryExtensions.GetOrAdd[TKey,TValue,TArg](ConcurrentDictionary2 dictionary, TKey key, Func
3 valueFactory, TArg arg)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.g__CreateController0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.d__7.MoveNext()
`
But if change Id back to int everything works well.
Can you help me with this trouble?
Thank you.
Thank you for all your work which saved a lot of my time.
It would have been better to have an option to set the SQL database credentials to Integrated windows security. I am not sure if I am asking something wrong since I am pretty new to this Asp.Net Core Api.
Thanks
Hi,
I tried setting up my project to use GUID instead of int on User and Role tables, however, I encounter the following error:
System.TypeLoadException: GenericArguments[0], 'Identity.Dapper.Entities.DapperIdentityUser
1[System.Guid]', on 'Identity.Dapper.Stores.DapperUserStore
7[TUser,TKey,TUserRole,TRoleClaim,TUserClaim,TUserLogin,TRole]' violates the constraint of type parameter 'TUser'.
at System.RuntimeTypeHandle.Instantiate(RuntimeTypeHandle handle, IntPtr* pInst, Int32 numGenericArgs, ObjectHandleOnStack type)
at System.RuntimeTypeHandle.Instantiate(Type[] inst)
at System.RuntimeType.MakeGenericType(Type[] instantiation)
I followed your instructions by adding the following to Startup.cs
services.AddIdentity<DapperIdentityUser<Guid>, DapperIdentityRole<Guid>>
I am getting a "Table Identity.IdentityUser does not exist" error when using mysql . My Database Name is DapperIdentityTest .
So I basically have a simple app with all of the classes extended (as discussed in a separate issue). I created 5 users and 3 roles and then made a simple UI where I can drag/drop a user(s) between the different roles. I'm using this as a simple test for the sql and dapper plugin stuff.
[HttpPost]
public async Task<IActionResult> UpdateUserRoles([FromBody] UpdateUserRolesViewModel request)
{
var success = true;
var message = "";
if (!User.IsOwner())
{
request.NewOwners = new List<int>();
message = "Admins cannot create Owners!";
}
var allRoles = new List<string>() { "Owner", "Admin", "User" };
try
{
var tasks = new List<Task>();
tasks.AddRange(request.NewOwners.Select(o => ProcessRoleChange(o, "Owner", allRoles)));
tasks.AddRange(request.NewAdmins.Select(a => ProcessRoleChange(a, "Admin", allRoles)));
tasks.AddRange(request.NewUsers.Select(u => ProcessRoleChange(u, "User", allRoles)));
await Task.WhenAll(tasks);
}
catch (Exception ex)
{
success = false;
message = ex.Message;
}
return Json(new { Success = success, Message = message });
}
private async Task ProcessRoleChange(int userId, string newRole, List<string> allRoles)
{
var user = await _userDataService.FindByIdAsync(userId.ToString());
if (user.Id == 0)
return;
var currRoles = await _userDataService.GetRolesAsync(user);
var toRemove = currRoles.Where(cr => allRoles.Contains(cr));
await Task.WhenAll(toRemove.Select(r => _userDataService.RemoveFromRoleAsync(user, r)));
await _userDataService.AddToRoleAsync(user, newRole);
}
The basics of this work fine, but if I do it a few times it will eventually start failing. I can debug into the catch and get this stack trace:
at System.Data.SqlClient.SqlTransaction.ZombieCheck()
at System.Data.SqlClient.SqlTransaction.Rollback()
at Identity.Dapper.Stores.DapperUserStore`7.RollbackTransaction() in C:\DevWork\SandboxCore\src\Identity.Dapper\Stores\DapperUserStore.cs:line 82
at Identity.Dapper.Stores.DapperUserStore`7.<UpdateAsync>d__63.MoveNext() in C:\DevWork\SandboxCore\src\Identity.Dapper\Stores\DapperUserStore.cs:line 931
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Identity.UserManager`1.<UpdateUserAsync>d__159.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Identity.UserManager`1.<AddToRoleAsync>d__99.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at SandboxCore.Controllers.AdminController.<ProcessRoleChange>d__4.MoveNext() in C:\DevWork\SandboxCore\src\SandboxCore\Controllers\AdminController.cs:line 93
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at SandboxCore.Controllers.AdminController.<UpdateUserRoles>d__3.MoveNext() in C:\DevWork\SandboxCore\src\SandboxCore\Controllers\AdminController.cs:line 69
My hunch here is that we just simply aren't thread safe when reusing the DbTransaction.
if (transaction == null)
{
using (conn = _connectionProvider.Create())
{
await conn.OpenAsync(cancellationToken);
return await insertFunction(conn);
}
}
else
{
conn = transaction.Connection;
return await insertFunction(conn);
}
This is a snippet from the UserRepository.AddToRole method. If the connection gets closed between the if check and the else block, we die in a blaze of glory, right?
Getting a
Reference to type 'IdentityBuilder' claims it is defined in 'Microsoft.AspNetCore.Identity', but it could not be found
on this line of code in startup.cs:
services.AddIdentity<DapperIdentityUser, DapperIdentityRole<int>>() .AddDapperIdentityForMySql();
ERROR:
2018-09-27 10:42:52.5350||ERROR|Identity.Dapper.Repositories.UserRepository|Login failed for user ''. System.Data.SqlClient.SqlException (0x80131904): Login failed for user ''.
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()
APPSETTINGS:
"ConnectionStrings": {
"EGestorBase": "Server=192.168.0.252;Database=EGestorBase;User Id=xxxxx;Password=xxxxx"
},
"DapperIdentity": {
"ConnectionString": "Server=192.168.0.252;Database=EGestorBase;User Id=xxxxx;Password=xxxxx"
},
"DapperIdentityCryptography": {
"Key": "RTU0NkM4REYyNzhDRDU5MzEwNjlCNTIyRTY5IUQ0RjI=",
"IV": "U29tZVJlYXxseUNvb2xJVg=="
},
Hi,
I'm trying to figure out how I would add claims to your project. For a simple example, I would like to attach MyCustomField that sits in the Users table. How would accomplish that? I was looking at ServiceCollectionExtension and I see you have some overrides that let you pass in TRoleClaim, but I'm not sure if this is what I'm looking for. And to be honest, I'm not sure how I would pass this along at startup.
hi,
i try to run your example. I use mysql and i created the database identity and the tables with the given sql script.
if i try to register a new user i get the follwing error msg:
An unhandled exception occurred while processing the request.
NullReferenceException: Object reference not set to an instance of an object.
Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory+d__5.MoveNext()
NullReferenceException: Object reference not set to an instance of an object.
Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory+<GenerateClaimsAsync>d__5.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory+<CreateAsync>d__9.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNetCore.Identity.SignInManager+<CreateUserPrincipalAsync>d__25.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNetCore.Identity.SignInManager+<SignInAsync>d__30.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Identity.Dapper.Samples.Web.Controllers.AccountController+<Register>d__9.MoveNext() in AccountController.cs
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
// Send an email with this link
//var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
//var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
//await _emailSender.SendEmailAsync(model.Email, "Confirm your account",
// $"Please confirm your account by clicking this link: <a href='{callbackUrl}'>link</a>");
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(3, "User created a new account with password.");
return RedirectToLocal(returnUrl);
}
AddErrors(result);
}
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeActionMethodAsync>d__12.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeNextActionFilterAsync>d__10.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeInnerFilterAsync>d__14.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeNextResourceFilter>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeFilterPipelineAsync>d__17.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker+<InvokeAsync>d__15.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__6.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext()
`
I only change your Adress field with FirstName and then i get this error.
Thanks for help
I try using openssl for encrypt my DB pass with command:
enc -aes256 -nosalt -k password -P
And my output key and iv:
key=5F4DCC3B5AA765D61D8327DEB882CF992B95990A9151374ABD8FF8C5A7A0FE08
iv =B7B4372CDFBCB3D16A2631B59B509E94
After encode to Base64 I get strings twice as long, than in your sample.
What am I doing wrong?
I'm confused about the tables in DBMS.
for example,if I want to implete the dapperidentity on the sqlserver ,how can I initalize the sqlserver? is there some sql-scripts to execute? and if has ,how to get the script?
First of all: THANK you for this! It's mostly been a breeze and I'm excited to see it work once I get this issue sorted out. Really hope this isn't an idiotic question.
In Startup.cs we configure the connection, crypto, and Identity options like so:
var section = Configuration.GetSection("DapperIdentity") as ConnectionProviderOptions; //Value is null!
services.ConfigureDapperConnectionProvider<PostgreSqlConnectionProvider>(Configuration.GetSection("DapperIdentity"))
.ConfigureDapperIdentityCryptography(Configuration.GetSection("DapperIdentityCryptography"))
.ConfigureDapperIdentityOptions(new DapperIdentityOptions { UseTransactionalBehavior = false });
Meanwhile in appsettings.json:
{
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"Console": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
},
"DapperIdentity": {
"ConnectionString": "User ID=postgres;Password=pass@;Host=localhost;Port=5432;Database=database;Pooling=true;",
"Username": "postgres",
"Password": "pass"
},
"DapperIdentityCryptography": {
"Key": "key==",
"IV": "iv="
}
}
When I inspect the variable "section" the value of it is null, despite the keys and values clearly being in the JSON. I've obviously looked at the source code where this config section is used with a model - but I'm not sure how it's supposed to with this issue. The end result of this is that when using the library I get the error:
"Parameter name: There's no DapperIdentity:ConnectionString configured. Please, register the value."
I've tried registering the config using your existing types myself in the main Configuration method:
services.Configure<ConnectionProviderOptions>(Configuration.GetSection("DapperIdentity"));
services.AddScoped<PostgreSqlConnectionProvider>();
But the DI system gets upset:
"Unable to resolve service for type 'Identity.Dapper.Connections.IConnectionProvider' while attempting to activate 'Identity.Dapper.Stores.DapperUserStore'"
It looks like this may be a mismatch of what you have for your examples and your source code - I've noticed that the latest NuGet packages have completely different method signatures from what's in the source code. Not sure if the latest package changes have to be checked in here.
Any guidance would be extremely helpful. Thanks again for your hard work here!
I am having hard time using string type for user id in custom user store. The code breaks at Activator.CreateInstance for idProperty under GetColumns method. Line number 32 om ColumnsBuilderExtensions.cs. On doing some research it is basically caused because System.String does not have a default constructor. Do have any suggestion around how to use string type id's using your your library?
hi,
i get the error:
Invalid cast from 'System.UInt64' to 'System.Guid'. System.InvalidCastException: Invalid cast from 'System.UInt64' to 'System.Guid'. at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) at Dapper.SqlMapper.Parse[T](Object value) in C:\projects\dapper\Dapper\SqlMapper.cs:line 2969 at Dapper.SqlMapper.<ExecuteScalarImplAsync>d__64
1.MoveNext() in C:\projects\dapper\Dapper\SqlMapper.Async.cs:line 1193`
this is my ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureDapperConnectionProvider<MySqlConnectionProvider>(Configuration.GetSection("DapperIdentity"))
.ConfigureDapperIdentityCryptography(Configuration.GetSection("DapperIdentityCryptography"))
.ConfigureDapperIdentityOptions(new DapperIdentityOptions { UseTransactionalBehavior = false }); //Change to True to use Transactions in all operations
services.AddIdentity<CustomUser, CustomRole>(x =>
{
x.Password.RequireDigit = false;
x.Password.RequiredLength = 1;
x.Password.RequireLowercase = false;
x.Password.RequireNonAlphanumeric = false;
x.Password.RequireUppercase = false;
})
.AddDapperIdentityFor<MySqlConfiguration, Guid>()
.AddDefaultTokenProviders();
services.AddMvc();
CustomUser and CustomRole:
public class CustomUser : DapperIdentityUser<Guid>
{
public string FirstName { get; set; }
public CustomUser() { }
public CustomUser(string userName) : base(userName) { }
}
public class CustomRole : DapperIdentityRole<Guid>
{
public CustomRole() { }
public CustomRole(string roleName) : base(roleName)
{
}
}
I changed the table for identityUser (MySql) like so:
CREATE TABLE IF NOT EXISTS `identityuser` (
`Id` CHAR(36) NOT NULL,
`Username` varchar(256) NOT NULL,
`Email` varchar(256) DEFAULT NULL,
`FirstName` varchar(256) DEFAULT NULL,
`EmailConfirmed` bit(1) NOT NULL,
`PasswordHash` longtext,
`SecurityStamp` varchar(38) DEFAULT NULL,
`PhoneNumber` varchar(50) DEFAULT NULL,
`PhoneNumberConfirmed` bit(1) NOT NULL,
`TwoFactorEnabled` bit(1) NOT NULL,
`LockoutEnd` datetime DEFAULT NULL,
`LockoutEnabled` bit(1) NOT NULL,
`AccessFailedCount` int(11) NOT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
Is that a mistake from my side or is that a general bug?
EDIT
if i register someone the data is insert in the database, but i get the error message from above
when i try to login user with PasswordSignInAsync it throws exception
fail: Identity.Dapper.Repositories.RoleRepository[0]
CommandText must be specified
System.InvalidOperationException: CommandText must be specified
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Dapper.SqlMapper.d__311.MoveNext() in C:\projects\dapper\Dapper\SqlMapper.Async.cs:line 389 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Identity.Dapper.Repositories.RoleRepository
4.<>c__DisplayClass8_0.<b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Identity.Dapper.Repositories.RoleRepository4.<GetClaimsByRole>d__8.MoveNext() fail: Identity.Dapper.Stores.DapperRoleStore[0] CommandText must be specified fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[0] An unhandled exception has occurred while executing the request System.ArgumentNullException: Value cannot be null. Parameter name: claims at System.Security.Claims.ClaimsIdentity.AddClaims(IEnumerable
1 claims)
at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory2.<GenerateClaimsAsync>d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()
at Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory1.<CreateAsync>d__9.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()
at Microsoft.AspNetCore.Identity.SignInManager1.<CreateUserPrincipalAsync>d__25.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()
at Microsoft.AspNetCore.Identity.SignInManager1.<SignInAsync>d__30.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Identity.SignInManager
1.d__52.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at Microsoft.AspNetCore.Identity.SignInManager
1.d__33.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at Microsoft.AspNetCore.Identity.SignInManager
1.d__34.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at HubPay.Api.Controllers.AccountController.d__7.MoveNext() in C:\Code\HubPayWeb\src\HubPay.Api\Controllers\AccountController.cs:line 63
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.d__7.MoveNext()
This is how i register a user
var result = await _userManager.CreateAsync(user, obj.Password);
if (result.Succeeded)
{
var roleString = RoleEnum.Customer.ToString().ToLower(CultureInfo.InvariantCulture);
var role = await _roleManager.FindByNameAsync(roleString);
if (role == null)
{
role = new Role { Name = roleString };
await _roleManager.CreateAsync(role);
if (!await _userManager.IsInRoleAsync(user, role.Name))
await _userManager.AddToRoleAsync(user, role.Name);
}
user.Roles.Add(new DapperIdentityUserRole<int> { RoleId = role.Id, UserId = user.Id });
var userDto = _mapper.Map<UserDto>(user);
return ApiResult(userDto, OperationStatus.Success);
}
am i missing something?
The UserRepository code uses Dapper's QueryAsync
, which will call DbConnection.ExecuteReaderAsync
. It's a long-standing bug in MySql.Data (bug 70111) that async I/O methods are not implemented; thus all these methods will fall back to running synchronously. (See also here and here on Stack Overflow.)
To fix this, you could switch to https://github.com/mysql-net/MySqlConnector, an OSS replacement for MySql.Data that supports true asynchronous I/O; it also has full .NET Standard/.NET Core support.
If you're interested in this, I'd be happy to open a PR.
(SqlServer)
Old:
New:
"SELECT Name FROM %SCHEMA%.%ROLETABLE%, %SCHEMA%.%USERROLETABLE% WHERE %SCHEMA%.%ROLETABLE%.Id = %SCHEMA%.%USERROLETABLE%.RoleId AND %SCHEMA%.%USERROLETABLE%.UserId = %ID%";
Only started testing so might find more.
I am trying to implement Identity.Dapper
I am getting a Not Implemented error while calling userManager.Users.FirstOrDefault() . I miss something ?
I've been working on an implementation of the user and roles stores myself using Dapper and looking at your implementation I noticed something that you might want to think about.
For example in your DapperUserStore class you have the AddToRole method. Within that you call this method:
var result = await _userRepository.AddToRole(user.Id, roleName, cancellationToken, _transaction);
That method will get the ID associated to the roleName provided and insert a new record associating the role to the user ID. Works fine. The issue is the way that the ASP.NET Core Identity UserManager class handles this. Take a look at this method found in the UserManager class:
public virtual async Task<IdentityResult> AddToRoleAsync(TUser user, string role)
{
ThrowIfDisposed();
var userRoleStore = GetUserRoleStore();
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
var normalizedRole = NormalizeKey(role);
if (await userRoleStore.IsInRoleAsync(user, normalizedRole, CancellationToken))
{
return await UserAlreadyInRoleError(user, role);
}
// Your implementation of this method is called.
await userRoleStore.AddToRoleAsync(user, normalizedRole, CancellationToken);
// Then the update user method is called.
return await UpdateUserAsync(user);
}
Essentially what will happen is your user repository method will be called to add the role and then the UserManager class will call UpdateUserAsync needlessly, because you handled associating the role already. This situation will happen in quite a few places when using the UserManager. The design the Identity Core folks are going for is to make all changes to the User entity and let the UpdateUserAsync method (which calls your UserStore UpdateAsync method) to do all the work.
I haven't totally gone over all the code in your repository, so maybe you've taken this into account already, but a lot of calls to the UserManager class will result extraneous Updates that aren't required. Not a major issue, but can hurt performance.
Why are you don't include "Id" in some queries of your UserRepository like in FindByLoginAsync?
When I try to sign in via external login, I use FindByLoginAsync, but I doesn't have Id in result and I can't init SignIn without user id.
Hello,
I'm trying to use this project, however, when I download the whole thing and I try to use the sample project, it doesn't work out of the box. I wanted to make a suggestion for the sample project to be configured so that it will work on any machine when downloaded.
I didn't have time to dive in depth and figure out what exactly is wrong, but one of the errors I get is:
Identity.Dapper.Samples.Web\Views\Account\Login.cshtml
'SignInManager' does not contain a definition for 'GetExternalAuthenticationSchemes' and no extension method 'GetExternalAuthenticationSchemes' accepting a first argument of type 'SignInManager' could be found (are you missing a using directive or an assembly reference?)
Operator '==' cannot be applied to operands of type 'method group' and 'int'
foreach statement cannot operate on variables of type '?' because '?' does not contain a public definition for 'GetEnumerator'
Do you have a working sample uploaded somewhere I can use to test and see how all this works?
This looks like a great package. I'd like to know what the license is to know if I can utilize it in my current project. Thanks!
P.S. I'm a big fan of MIT :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.