Reputation: 81
In my case i have existing mvc project on azure-cloud.It was necessary to add a web api to identify external users, and it was also decided to use Mysql for storing information about the user. I configured the web api using the following instructions from microsoft: https://learn.microsoft.com/en-us/aspnet/identity/overview/extensibility/implementing-a-custom-mysql-aspnet-identity-storage-provider After provider was setted up, i used default asp.net web-api application, to set the rest fuinctionality. Here's my configurations:
IdentityModels.cs
using System.Data.Entity;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using AspNet.Identity.MySQL;
using **.Web.App_Start;
namespace **.Web.Models
{
public class CustomerPortalUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<CustomerPortalUser> manager, string authenticationType)
{
var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
return userIdentity;
}
public bool IsActive { get; set; }
public string IdNumber { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string PostalCode { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Country { get; set; }
public string City { get; set; }
}
public class PortalUserRole : IdentityRole
{
public PortalUserRole() : base() { }
public PortalUserRole(string name) : base(name) { }
}
public class PortalUserDbContext : MySQLDatabase
{
public PortalUserDbContext(string connectionName)
: base(connectionName)
{
}
public static PortalUserDbContext Create()
{
return new PortalUserDbContext("PortalAuth");
}
}
}
AccountController.cs Register Method:
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
BaseResponse response = new BaseResponse();
response.IsSuccess = false;
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var user = new CustomerPortalUser() {
UserName = model.Email,
Email = model.Email,
Address1 = model.Address1,
Address2 = model.Address2,
Address3 = model.Address3,
PostalCode = model.PostalCode,
City = model.City,
IdNumber = model.IdNumber,
LastName = model.LastName,
FirstName = model.FirstName
};
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
response.IsSuccess = true;
return Ok();
}
IdentityConfig.cs:
public class CustomerPortalUserManager : UserManager<CustomerPortalUser>
{
public CustomerPortalUserManager(IUserStore<CustomerPortalUser> store)
: base(store)
{
}
public static CustomerPortalUserManager Create(IdentityFactoryOptions<CustomerPortalUserManager> options, IOwinContext context)
{
var manager = new CustomerPortalUserManager(new UserStore<CustomerPortalUser>(context.Get<PortalUserDbContext>()));
manager.UserValidator = new UserValidator<CustomerPortalUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<CustomerPortalUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
And my Startup.Auth.cs:
public void ConfigurePortalAuth(IAppBuilder app)
{
app.CreatePerOwinContext(PortalUserDbContext.Create);
app.CreatePerOwinContext<CustomerPortalUserManager>(CustomerPortalUserManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/portalApi/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/portalApi/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
}
But when i'm trying to register new user with my custom fields
public string IdNumber { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string PostalCode { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Country { get; set; }
public string City { get; set; }
User will be created with default identity values such a Password and UserName that i passed in request. But all my custom values will be equal NULL, instead of my values passed in the request. Also, if i will get user info like this:
CustomerPortalUser user = await userManager.FindAsync(context.UserName, context.Password);
Even if custom values will be not null in database, they will be null in result above. Package used:
AspNet.Identity.MySQL 1.0.0.38741
MySql.Data 6.10.9
MySql.Data.Entity 6.10.9
Upvotes: 1
Views: 233
Reputation: 1801
Why not try using the IdentityDbContext
as base class for your DbContext where you can pass the IdenityUser
and the IdentityRole
models.
public class PortalUserDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int>
I am not familiar with this MySQLDatabase
class and where it comes from but it doesn't seem to accept your custom models. At least not shown as a snippet.
I am using ASP.Net Identity and EF with MySQL as well and as an adaptor I am happy with the Pomelo.EntityFrameworkCore.MySql
NuGet package - if you have any issues with data on SQL level you might opt for this one.
Upvotes: 0