My application is MVC5, I tried to allow duplicate email address using the following:
public async Task<ActionResult> AddUser (UserRegisterViewModel userViewModel)
{
......
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
......
};
var adminresult = await UserManager.CreateAsync(user);
var result = await UserManager.AddToRolesAsync(user.Id, user.Profession);
UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager)
{
RequireUniqueEmail = false
};
if (adminresult.Succeeded)
{
....
return RedirectToAction("VisitInfo", "Visit");
}
if (!adminresult.Succeeded)
{
var er = adminresult.Errors.FirstOrDefault();
ViewBag.Error = er;
return View(userViewModel);
}
return RedirectToAction("VisitInfo", "Visit");
}
return View();
}
By adding RequireUniqueEmail = false. It did not work, the page is redirected to login page!!
My question is could I allow duplicate emails just for this action, and why I get redirected to login page?
If you are using the default MVC 5 project template, the proper way is to set the rules in IdentityConfig.cs instead of in the registration controller.
Open App_Start\IdentityConfig.cs and edit this line:
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = false //<-- the default is true
};
....<snip>....
you have to add below lines in configureservices
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.User.RequireUniqueEmail = false;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
Thanks to Brendan, I moved
UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager)
{
RequireUniqueEmail = false
};
Before:
var adminresult = await UserManager.CreateAsync(user);
For .NET Core and .NET5+ it needs to be added as an option to the IServiceCollection
services.AddIdentityCore<AppUser>(opt =>
{
opt.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<DataContext>();
Related
I have three projects. One is Dot net core MVC, two are API projects. MVC is calling one API for user details. When user details are asked, I am sending message to queue through MassTransit. I am seeing skipped queue. There's consumer in third project which is API project.
I tried to make another solution for a demo with same configuration. It's running fine.
Below is MVC Razor page code..
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
ReturnUrl = returnUrl;
if (ModelState.IsValid)
{
var user = await AuthenticateUser(Input.Email);
if (user == null)
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
#region snippet1
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("FullName", user.FullName),
new Claim(ClaimTypes.Role, "Administrator"),
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(15),
IsPersistent = true,
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
#endregion
_logger.LogInformation("User {Email} logged in at {Time}.",
user.Email, DateTime.UtcNow);
return LocalRedirect(Url.GetLocalUrl(returnUrl));
}
return Page();
}
private async Task<ApplicationUser> AuthenticateUser(string email)
{
if (!string.IsNullOrEmpty(email))
{
using (var client = new System.Net.Http.HttpClient())
{
var request = new System.Net.Http.HttpRequestMessage();
request.RequestUri = new Uri("http://localhost:52043/api/user?uName=" + email); // ASP.NET 3 (VS 2019 only)
var response = await client.SendAsync(request);
var customer = Newtonsoft.Json.JsonConvert.DeserializeObject<Customers>(response.Content.ReadAsStringAsync().Result);
return new ApplicationUser()
{
Email = email,
FullName = customer.FullName
};
}
}
else
{
return null;
}
}
MVC Startup:
services.AddMassTransit(x =>
{
x.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(cfg =>
{
// configure health checks for this bus instance
cfg.UseHealthCheck(provider);
cfg.Host("rabbitmq://localhost");
}));
});
services.AddMassTransitHostedService();
User API Code - 52043:
[HttpGet]
public async Task<IActionResult> Get(string uName)
{
var customer = _userRepository.GetCustomerByUserName(uName);
Uri uri = new Uri("rabbitmq://localhost/loginqueue");
var endpoint = await _bus.GetSendEndpoint(uri);
await endpoint.Send(new LoginObj() { NoteString = customer.FullName + " has logged in at " + DateTime.Now.ToString() });
return Json(customer);
}
Logging API - Consumer Code:
public class LoginConsumer : IConsumer<LoginObj>
{
private readonly ILogger<object> _logger;
public LoginConsumer(ILogger<object> logger)
{
_logger = logger;
}
public async Task Consume(ConsumeContext<LoginObj> context)
{
var data = context.Message;
_logger.LogInformation(data.ToString());
}
}
Login API Startup:
services.AddMassTransit(x =>
{
x.AddConsumer<LoginConsumer>();
x.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(cfg =>
{
// configure health checks for this bus instance
cfg.UseHealthCheck(provider);
cfg.Host("rabbitmq://localhost");
cfg.ReceiveEndpoint("loginqueue", ep =>
{
ep.PrefetchCount = 16;
ep.UseMessageRetry(r => r.Interval(2, 100));
ep.ConfigureConsumer<LoginConsumer>(provider);
});
}));
});
services.AddMassTransitHostedService();
As per the documentation:
MassTransit uses the full type name, including the namespace, for message contracts. When creating the same message type in two separate projects, the namespaces must match or the message will not be consumed.
Make sure that your message type has the same namespace/type in each project.
I've seen numerous examples of how to use JWT authentication with Angular, React, Vue etc... clients but can't find any examples of using JWT authentication with ASP.NET Core (specifically 2.2) Web App Mvc.
Does anyone have any examples or advice on how to do this?
Thanks,
You can use this class based on nuget package JWT 3.0.3
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Newtonsoft.Json;
using System;
namespace Common.Utils
{
public class JwtToken
{
private IJwtEncoder encoder;
private IJwtDecoder decoder;
/// <remarks>
/// This requires a key value randomly generated and stored in your configuration settings.
/// Consider that it is a good practice use keys as at least long as the output digest bytes
/// length produced by the hashing algorithm used. Since we use an HMAC-SHA-512 algorithm,
/// then we can provide it a key at least 64 bytes long.
/// <see cref="https://tools.ietf.org/html/rfc4868#page-7"/>
/// </remarks>
public string SecretKey { get; set; }
public JwtToken()
{
IJwtAlgorithm algorithm = new HMACSHA512Algorithm();
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider datetimeProvider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, datetimeProvider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
decoder = new JwtDecoder(serializer, validator, urlEncoder);
SecretKey = "";
}
public JwtToken(string secretKey) : this()
{
SecretKey = secretKey;
}
public bool IsTokenValid(string token)
{
return !string.IsNullOrWhiteSpace(DecodeToken(token));
}
public string GetToken(object payload)
{
try
{
return encoder.Encode(payload, SecretKey);
}
catch (Exception)
{
return encoder.Encode(new DataModel(payload), SecretKey);
}
}
public string DecodeToken(string token)
{
try
{
if (string.IsNullOrWhiteSpace(token) || token == "null")
{
return null;
}
return decoder.Decode(token, SecretKey, true);
}
catch (TokenExpiredException)
{
return null;
}
catch (SignatureVerificationException)
{
return null;
}
}
public T DecodeToken<T>(string token) where T : class
{
try
{
if (string.IsNullOrWhiteSpace(token))
{
return null;
}
return decoder.DecodeToObject<T>(token, SecretKey, true);
}
catch (TokenExpiredException)
{
return null;
}
catch (SignatureVerificationException)
{
return null;
}
catch (Exception)
{
var data = decoder.DecodeToObject<DataModel>(token, SecretKey, true).Data;
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(data));
}
}
}
public class DataModel
{
public DataModel(object data)
{
Data = data;
}
public object Data { get; set; }
}
}
Then in your Startup class Configure method set the jwt middleware
for check authentication status of each request:
app.Use((context, next) =>
{
// verify app access token if not another service call
var appAccessToken = context.Request.Headers["Authorization"];
if (appAccessToken.Count == 0)
{
context.Items["User"] = null;
}
else
{
var token = appAccessToken.ToString().Replace("Bearer ", "");
var jwtToken = new JwtToken(config.JwtTokenSecret); //you need a secret (with requirements specified above) in your configuration (db, appsettings.json)
if (string.IsNullOrWhiteSpace(token) || !jwtToken.IsTokenValid(token))
{
context.Response.StatusCode = 401;
return Task.FromResult(0);
}
dynamic user = jwtToken.DecodeToken<dynamic>(token);
var cachedToken = cache.Get(user.Id); //you need some cache for store your token after login success and so can check against
if (cachedToken == null || cachedToken.ToString() != token)
{
context.Response.StatusCode = 401;
return Task.FromResult(0);
}
context.Items["User"] = new Dictionary<string, string>() {
{ "FullName",user.Name?.ToString()},
{ "FirstName",user.FirstName?.ToString()},
{ "LastName",user.LastName?.ToString()},
{ "Role",user.Role?.ToString()},
{ "Email",user.Email?.ToString()}
};
}
return next();
});
And finally you need generate the token and return it after
authentication:
[AllowAnonymous]
public IActionResult Login(string username, string password)
{
User user = null; //you need some User class with the structure of the previous dictionary
if (checkAuthenticationOK(username, password, out user)) //chackAuthenticationOk sets the user against db data after a succesfull authentication
{
var token = new JwtToken(_config.JwtTokenSecret).GetToken(user); //_config is an object to your configuration
_cache.Set(user.id, token); //store in the cache the token for checking in each request
return Ok(token);
}
return StatusCode(401, "User is not authorized");
}
Add following code to startup
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Issuer"],
ValidAudience = Configuration["Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SigningKey"]))
};
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env,, ILoggerFactory loggerFactory)
{
app.UseAuthentication();
}
Code for login action in AccountController
[Route("api/[controller]")]
public class AccountController : Controller
{
[AllowAnonymous]
[HttpPost]
[Route("login")]
public IActionResult Login([FromBody]LoginViewModel loginViewModel)
{
if (ModelState.IsValid)
{
var user = _userService.Authenticate(loginViewModel);
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, loginViewModel.Username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var token = new JwtSecurityToken
(
issuer: _configuration["Issuer"],
audience: _configuration["Audience"],
claims: claims,
expires: DateTime.UtcNow.AddDays(10),
notBefore: DateTime.UtcNow,
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SigningKey"])),
SecurityAlgorithms.HmacSha256)
);
return Ok(new
{
access_token = new JwtSecurityTokenHandler().WriteToken(token),
expires_in = (int)token.ValidTo.Subtract(DateTime.UtcNow).TotalSeconds,// TimeSpan.FromTicks( token.ValidTo.Ticks).TotalSeconds,
sub = loginViewModel.Username,
name = loginViewModel.Username,
fullName = user.FullName,
jobtitle = string.Empty,
phone = string.Empty,
email = user.EmailName,
});
}
}
}
I assume you have implemented JWT on the server side. To handle this on client side, first you have to add token to web browser local storage. Add to your main layout javascript (let's named it AuthService.js)
below code adds token to local storage after login button clicked. gettokenfromlocalstorage() retrieve token from local storage.
<script>
var token = "";
function Loginclick() {
var form = document.querySelector('form');
var data = new FormData(form);
var authsevice = new AuthService();
authsevice.LogIn(data.get("username").toString(), data.get("password").toString());
}
function gettokenfromlocalstorage() {
var authserv = new AuthService();
var mytoken = authserv.getAuth();
authserv.LogOut();
}
var AuthService = /** #class */ (function () {
function AuthService() {
this.authKey = "auth";
}
AuthService.prototype.LogIn = function (username, password) {
this.username = username;
this.password = password;
this.grant_type = "password";
this.client_id = "MyClientId";
var loginurl = "/api/Token/Auth";
var xhr = new XMLHttpRequest();
xhr.open("POST", loginurl, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(this));
xhr.onreadystatechange = function () {
console.log("onreadystatechange");
};
xhr.onerror = function () {
var aaa = this.responseText;
};
xhr.onload = function () {
var data = JSON.parse(this.responseText);
var auth = new AuthService();
auth.setAuth(data);
};
};
AuthService.prototype.LogOut = function () {
this.setAuth(null);
return true;
};
AuthService.prototype.setAuth = function (auth) {
if (auth) {
localStorage.setItem(this.authKey, JSON.stringify(auth));
}
else {
localStorage.removeItem(this.authKey);
}
return true;
};
AuthService.prototype.getAuth = function () {
var i = localStorage.getItem(this.authKey);
return i === null ? null : JSON.parse(i);
};
AuthService.prototype.isLoggedIn = function () {
return localStorage.getItem(this.authKey) !== null ? true : false;
};
return AuthService;
}());
var aa = new AuthService();
var gettoken = aa.getAuth();
if (gettoken !== null) {
token = gettoken.token;
}
</script>
To add token to the header of each anchor tag put below script also to
your main layout.
<script>
var links = $('a');
for (var i = 0; i < links.length; i++) {
links[i].onclick = function check() {
addheader(this.href);
return false;
}
}
function addheader(object) {
let xhr = new XMLHttpRequest();
xhr.open("GET", object, true);
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.send(null);
xhr.onload = function () {
window.history.pushState("/", "", xhr.responseURL);
//mycontainer is a div for parialview content
$("#mycontainer").html(xhr.responseText);
window.onpopstate = function (e) {
if (e.state) {
$("html").html = e.state;
document.title = e.state.pageTitle;
}
};
};
}
</script>
Remember that using of this approach, each view has to be loaded as a partial view.
If you insert url address in a web browser bar directly this solution doesn't work. I haven't figured it out yet. That's why to manage token authentication is better using single page application, not multipage application.
You can use this boilerplate to understand how to implement JWT tokenization with .Net Core. In the project you can find JWT, Swagger and EF features.
I recently added Identity to my ASP.NET project, but I'm having trouble checking user roles.
I originally create my Admin role in Startup.cs:
private void createRolesandUsers()
{
ApplicationDbContext context = new ApplicationDbContext();
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
if (!roleManager.RoleExists("Admin"))
{
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = "Admin";
roleManager.Create(role);
var user = new ApplicationUser();
user.UserName = "admin";
user.Email = "admin#tpms.com";
string userPWD = "********";
var chkUser = UserManager.Create(user, userPWD);
if (chkUser.Succeeded)
{
var result1 = UserManager.AddToRole(user.Id, "Admin");
}
}
}
In my UserController.cs, I have a function to check if the user is an admin:
public Boolean isAdminUser()
{
if (User.Identity.IsAuthenticated)
{
var user = User.Identity;
ApplicationDbContext context = new ApplicationDbContext();
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var s = UserManager.GetRoles(user.GetUserId());
if (s[0].ToString() == "Admin")
{
return true;
}
else
{
return false;
}
}
return false;
}
However, I can't seem to find a way to access the isAdminUser() function from both my Views and my Controllers.
I've done a little bit of research the IsUserInRole() function, but when I tried:
#if (Roles.IsUserInRole(User.Identity.Name, "Admin")) { Html.ActionLink("Edit", "Edit", new { id=item.GuestID }); }
The if statement always returns false.
Try to use HttpContext.Current.User.IsInRole("Admin"); as Roles.IsUserInRole related to old membership provider under System.Web.Security namespace and need roleManager provider configuration in web.config.
#if(HttpContext.Current.User.IsInRole("Admin"))
{
Html.ActionLink("Edit", "Edit", new { id = item.GuestID });
}
Another way is to use UserManager
userManager.IsInRole("userId","Admin")
I'm trying to implement asp.net core cookie-based authentication. So I have added the code below to my startup.cs
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.AccessDeniedPath = new PathString("/login");
options.LoginPath = new PathString("/login");
options.SlidingExpiration = true;
});
and I'm sign-in using the code below
[HttpPost]
[ValidateAntiForgeryToken]
[Route("login")]
public async Task<IActionResult> Login(AuthViewModel authView)
{
if (ModelState.IsValid)
{
var (status, message, SigninUser) = await authentication.Authenticate(new User()
{
email = authView.Email,
pwd = authView.Password
});
if (status)
{
List<Claim> claims = new List<Claim>
{
new Claim(ClaimTypes.Name, "App Member"),
new Claim(ClaimTypes.Email, SigninUser.email)
};
ClaimsIdentity identity = new ClaimsIdentity(claims, "cookie");
ClaimsPrincipal principal = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(
scheme: CookieAuthenticationDefaults.AuthenticationScheme,
principal: principal,
properties: new AuthenticationProperties
{
IsPersistent = authView.RememberMe,
ExpiresUtc = DateTime.UtcNow.AddYears(1)
});
HttpContext.Session.Set<User>("session_user", SigninUser);
if (Url.IsLocalUrl(authView.returnUrl))
return Redirect(authView.returnUrl);
else
return RedirectToAction("Index");
}
else
{
authView.Status = false;
authView.Message = message;
}
}
else
{
string message = string.Join(" | ", ModelState.Values.SelectMany(e => e.Errors).Select(v => v.ErrorMessage));
authView.Status = false;
authView.Message = message;
}
return View(authView);
}
This works fine. But when I keep the browser IDLE for like 30 minutes the "session_user" session variable get expired and the user still gets authenticated. How can I resolve this?
Also using cookie-based authentication can have a performance penalty?
Thanks
I have been playing about with the new MVC 5, I have a few models, controller and views setup using code first migrations.
My question is how do I seed users and roles? I currently seed some reference data in my Seed method in Configuration.cs. But it looks to me that the user and roles tables are not created until something first hits the AccountController.
I currently have two connection strings so I can separate my data from my authentication into different databases.
How can I get the user, roles, etc tables populate along with my others? And not when the account controller is hit?
Here is example of usual Seed approach:
protected override void Seed(SecurityModule.DataContexts.IdentityDb context)
{
if (!context.Roles.Any(r => r.Name == "AppAdmin"))
{
var store = new RoleStore<IdentityRole>(context);
var manager = new RoleManager<IdentityRole>(store);
var role = new IdentityRole { Name = "AppAdmin" };
manager.Create(role);
}
if (!context.Users.Any(u => u.UserName == "founder"))
{
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
var user = new ApplicationUser {UserName = "founder"};
manager.Create(user, "ChangeItAsap!");
manager.AddToRole(user.Id, "AppAdmin");
}
}
I used package-manager "update-database". DB and all tables were created and seeded with data.
It's a small addition, but to anyone having the "UserId not found." message when trying to seed: (Tom Regan had this question in the comments, and I was stuck on it myself for a while)
This means that the manager.Create(user, "ChangeItAsap!") was not successful.
This might have a different reason, but for me it was because my password was not succeeding its validation.
I had a custom passwordvalidator, which was not being called when seeding the database, so the validation rules i was used to (minlength 4 instead of default 6) did not apply. Make sure your password (and all other fields for that matter) is passing validation.
This is my method base on Valin answer, I have added roles in db and added password for user. This code is placed in Seed() method in Migrations>Configurations.cs.
// role (Const.getRoles() return string[] whit all roles)
var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
for (int i = 0; i < Const.getRoles().Length; i++)
{
if (RoleManager.RoleExists(Const.getRoles()[i]) == false)
{
RoleManager.Create(new IdentityRole(Const.getRoles()[i]));
}
}
// user
var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var PasswordHash = new PasswordHasher();
if (!context.Users.Any(u => u.UserName == "admin#admin.net"))
{
var user = new ApplicationUser
{
UserName = "admin#admin.net",
Email = "admin#admin.net",
PasswordHash = PasswordHash.HashPassword("123456")
};
UserManager.Create(user);
UserManager.AddToRole(user.Id, Const.getRoles()[0]);
}
Here i have an very easy,clean and smooth solution.
protected override void Seed(UserContext context)
{
//Step 1 Create the user.
var passwordHasher = new PasswordHasher();
var user = new IdentityUser("Administrator");
user.PasswordHash = passwordHasher.HashPassword("Admin12345");
user.SecurityStamp = Guid.NewGuid().ToString();
//Step 2 Create and add the new Role.
var roleToChoose = new IdentityRole("Admin");
context.Roles.Add(roleToChoose);
//Step 3 Create a role for a user
var role = new IdentityUserRole();
role.RoleId = roleToChoose.Id;
role.UserId = user.Id;
//Step 4 Add the role row and add the user to DB)
user.Roles.Add(role);
context.Users.Add(user);
}
protected override void Seed(ApplicationDbContext context)
{
SeedAsync(context).GetAwaiter().GetResult();
}
private async Task SeedAsync(ApplicationDbContext context)
{
var userManager = new ApplicationUserManager(new UserStore<ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(context));
var roleManager = new ApplicationRoleManager(new RoleStore<ApplicationRole, int, ApplicationUserRole>(context));
if (!roleManager.Roles.Any())
{
await roleManager.CreateAsync(new ApplicationRole { Name = ApplicationRole.AdminRoleName });
await roleManager.CreateAsync(new ApplicationRole { Name = ApplicationRole.AffiliateRoleName });
}
if (!userManager.Users.Any(u => u.UserName == "shimmy"))
{
var user = new ApplicationUser
{
UserName = "shimmy",
Email = "shimmy#gmail.com",
EmailConfirmed = true,
PhoneNumber = "0123456789",
PhoneNumberConfirmed = true
};
await userManager.CreateAsync(user, "****");
await userManager.AddToRoleAsync(user.Id, ApplicationRole.AdminRoleName);
}
}
Looks like they changes the way authentication works in MVC5, changed my Global.asax.cs to the following did the trick!
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Threading.Tasks;
using MvcAuth.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using System.Threading;
using Microsoft.AspNet.Identity.EntityFramework;
namespace MvcAuth
{
public class MvcApplication : System.Web.HttpApplication
{
async Task<bool> AddRoleAndUser()
{
AuthenticationIdentityManager IdentityManager = new AuthenticationIdentityManager(
new IdentityStore(new ApplicationDbContext()));
var role = new Role("Role1");
IdentityResult result = await IdentityManager.Roles.CreateRoleAsync(role, CancellationToken.None);
if (result.Success == false)
return false;
var user = new ApplicationUser() { UserName = "user1" };
result = await IdentityManager.Users.CreateLocalUserAsync(user, "Password1");
if (result.Success == false)
return false;
result = await IdentityManager.Roles.AddUserToRoleAsync(user.Id, role.Id, CancellationToken.None);
return result.Success;
}
protected async void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
bool x = await AddRoleAndUser();
}
}
}
write this code in your Migration Configuration.
note: Use ApplicationDbContext in Configuration Class.
internal sealed class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = false;
}
protected override void Seed(ApplicationDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
context.Roles.AddOrUpdate(p =>
p.Id,
new IdentityRole { Name = "Admins"},
new IdentityRole { Name = "PowerUsers" },
new IdentityRole { Name = "Users" },
new IdentityRole { Name = "Anonymous" }
);
}
}