grandchamp / Identity.Dapper

Identity package that uses Dapper instead EntityFramework for use with .NET Core
MIT License
268 stars 62 forks source link

Providing Configuration section in .NET Core 2.0 during setup doesn't appear to work. #48

Closed Ryanman closed 6 years ago

Ryanman commented 6 years ago

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!

grandchamp commented 6 years ago

Hi @Ryanman. In version 0.6 i had made a several changes on how the extension methods are called. But i had updated the project Readme and the sample project. Did you check out?

Basically, i had replaced the old ConfigureDapperConnectionProvider by ConfigureDapperConnectionProvider<T> where T is the DBMS configuration class (Eg: SqlServerConfiguration). And the old AddDapperIdentityForXXX where XXX is your DBMS by AddDapperIdentityFor<T>.

You don't have to add anything directly to DI, all this extension methods does this for you.

Does your key and iv base 64 encoded?

Can you upload your code somewhere?

Ryanman commented 6 years ago

It looks like the readme and the sample project do things differently right now, unfortunately. The sample project appears to configure Identity.Dapper the old way, with "ConfigureDapperConnectionProvider".

The readme uses "ConfigureDapperFor". But that method is found only in the readme. It's not anywhere in the source code currently uploaded to Github, and doesn't appear to be in the 0.6 NuGet Package. As a result, when attempting to use it I get an error: Error CS1061 'IServiceCollection' does not contain a definition for 'ConfigureDapperFor' and no extension method 'ConfigureDapperFor' accepting a first argument of type 'IServiceCollection' could be found (are you missing a using directive or an assembly reference?)

Even once we sort out which of these to use, I'm a bit worried it won't solve the main problem - namely that in .NET Core 2.0 I'm getting null values for this configuration section to pass to the helpers you've made. For instance, in my code above I assume we're supposed to be passing the DapperIdentity section with the child elements

to your helper methods. In reality I can only pass in one of those at a time by doing something like (Ironically still containing the username and pass): var x = Configuration.GetSection("DapperIdentity:ConnectionString");

This same problem will appear when I use .ConfigureDapperIdentityCryptography - when I pass in the "DapperIdentityCryptography" parent section of appsettings.json it'll have null values to bind against because the config section isn't strongly typed.

Does all of this make sense? I feel like all of the issues I'm having so far relate to the configuration portion of the library, with the relevant code shown above. I'm doing something wrong as every time I try to save a new user with the library I'm getting "Parameter name: There's no DapperIdentity:ConnectionString configured. Please, register the value.".

grandchamp commented 6 years ago

@Ryanman yes, there was a wrong method on README. I've fixed it. The sample project works fine now, i had just updated the appsettings.json file (see https://github.com/grandchamp/Identity.Dapper/commit/7062b1daf125534661ff6ed4a709df91ee05287d). Check it out.

I'll make integration tests for the samples too, if i had it you probably won't have this issue.

Ryanman commented 6 years ago

@grandchamp the changes to the readme etc. have been successful! I'm still having a couple issues - if you can work with me through them that'd be awesome, but if you're busy no big deal.

I think it's safe to close this specific issue now. I really appreciate it.

grandchamp commented 6 years ago
  1. Yes, it's possible. Today you do:
            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>()
                    .AddDefaultTokenProviders();

You can change to:

            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(new PostgreSqlConfiguration
                    {
                        SchemaName = "myschema"
                    })
                    .AddDefaultTokenProviders();
  1. Well, what i do is generate a random key on https://passwordsgenerator.net/, chosing a 32 size and marking "Exclude Ambiguous Characters". Then i base64 encode it (Notepad++ do it) and put on Key. Then i do the same (changing to 16 size) for IV.