Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get users from a existing database for identityServer4

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

like image 673
eldios1981 Avatar asked May 15 '17 15:05

eldios1981


2 Answers

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://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity

like image 55
kg743 Avatar answered Oct 01 '22 00:10

kg743


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);
    }
like image 45
moritzg Avatar answered Oct 01 '22 00:10

moritzg