10

i try to understand how i can bind users (email, password, firstname, lastname and os on) which are stored in an existing database (located: localhost:3306) into my identityserver4 project so that i can use these information to login a user or register a new user into that database?

I read some tutorials (specially http://docs.identityserver.io/en/release/quickstarts/8_entity_framework.html) but i think this is always for db in the same project. my db isn´t in the same project.

In this context i read about asp.net-core Identity. but i don´t understand completely how that´s related.

Can someone tell me how can i bind a db in my project and what´s the role of identity with application User and so on?

thanks in advance

eldios1981
  • 509
  • 2
  • 12
  • 26
  • Implement some sort of user store, like the Teat one here but point it to your external DB. github.com/IdentityServer/IdentityServer4.Samples/blob/release/Quickstarts/8_EntityFrameworkStorage/src/QuickstartIdentityServer/Quickstart/Account/AccountController.cs – Mardoxx May 15 '17 at 16:35

2 Answers2

5

This article is more relevant to your situation. The one you linked is for configuration data and not for user data: http://docs.identityserver.io/en/release/quickstarts/6_aspnet_identity.html

In short, you want to access your user data through Asp.Net Core Identity. You need to:

  • Make a user class containing the relevant fields as your database
  • Create an EntityFramework DbContext class to map your database to your class
  • Register your user class and dbcontext with aspnet core identity
  • Tell IdentityServer to use AspNetIdentity

This is what your Startup ConfigureServices method might look like once implemented. Not pictured here is the DbContext and User classes you need to make.

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext<YourUserStoreDbContextHere>(options =>
            options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

    services.AddIdentity<YourUserClassHere, YourRoleClassHereIfAny>()
        .AddEntityFrameworkStores<YourUserStoreDbContextHere>()
        .AddDefaultTokenProviders();

    services.AddIdentityServer()
        // Other config here
        .AddAspNetIdentity<YourUserClassHere>();
}

Refer to the docs on AspNet Identity for details on configuring your user class and dbcontext: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity

kg743
  • 673
  • 5
  • 13
  • Hi, you bring a lot of light into the dark. I have a question about the User class. Without identity i have a class users (like the name of the table) and in this class i defined all details for users (like email,street, gender..) If i use Identity i have a ApplicationUser class which inherits from IdentityUser. Is this the same class like users without Identity? Here i have to add special informations (like gender) which are not part of the IdentityUser? I hope you can understand what i mean. – eldios1981 May 16 '17 at 10:49
4

You need to implement your own UserStore (example)

public async Task<TapkeyUser> ValidateCredentialsAsync(string username, string password)
{
      //This is pseudo-code implement your DB logic here
      if (database.query("select id from users where username = username and password = password") 
      {
           return new User(); //return User from Database here 
      } else {
           return null;
      }        
}

And use this in your AccountController:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginInputModel model)
    {
        if (ModelState.IsValid)
        {
            // use our custom UserStore here
 -------->  if (_users.ValidateCredentials(model.Username, model.Password))
            {
                AuthenticationProperties props = null;
                // only set explicit expiration here if persistent. 
                // otherwise we reply upon expiration configured in cookie middleware.
                if (AccountOptions.AllowRememberLogin && model.RememberLogin)
                {
                    props = new AuthenticationProperties
                    {
                        IsPersistent = true,
                        ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)
                    };
                };

                // issue authentication cookie with subject ID and username
                var user = _users.FindByUsername(model.Username);
                await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username));
                await HttpContext.Authentication.SignInAsync(user.SubjectId, user.Username, props);

                // make sure the returnUrl is still valid, and if yes - redirect back to authorize endpoint or a local page
                if (_interaction.IsValidReturnUrl(model.ReturnUrl) || Url.IsLocalUrl(model.ReturnUrl))
                {
                    return Redirect(model.ReturnUrl);
                }

                return Redirect("~/");
            }

            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials"));

            ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage);
        }

        // something went wrong, show form with error
        var vm = await _account.BuildLoginViewModelAsync(model);
        return View(vm);
    }
moritzg
  • 4,266
  • 3
  • 37
  • 62