How to use Roles in user identity in MVC 5 - asp.net-mvc

I want to use asp.net useridentity in mvc 5, I do these steps:
1) create a mvc project.
2) create my own database and change the connectionstring in web.config form:
to:
3) I run the project and create a new user to add related table to my database.
4) I wanted to add a role to a user after registration a user like this code in accountControler:
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
//******************* Add Role To User **************
if (!Roles.RoleExists("Member"))
Roles.CreateRole("Member");
Roles.AddUserToRole(model.Email, "Member");
//****************************************************
await SignInAsync(user, isPersistent: false);
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking here");
return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
5) I add
<roleManager enabled="true">
into:
<system.web></system.web>
when I create a new user my user register well but user not add to the role, and when I do this VS Create a new database in App_Data with name "ASPNETDB.MDF".
so I found a new article that explain about Role Provider Settings in web.config and:
6) I add
<roleManager enabled="true">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider" connectionStringName="DefaultConnection" applicationName="/" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
</roleManager>
into :
<system.web></system.web>
but when I want to register new user I found this Error:
Could not find stored procedure 'dbo.aspnet_CheckSchemaVersion'.
Now I think my problem is when I do step 3 it will not completely create the user identity database and stored procedure! Am I using role true for MVC 5 ? Please help me to solve this problem!

When you write
!Roles.RoleExists("Member")
you are not using ASP.NET Identity! instead, you should use ApplicationRole so it extends the IdentityRole class
In addition, you don't need to tell the AspNetSqlRoleProvider in your config file. Asp.Net Identity is something different. In Asp.Net Identity there is a class named ApplicationRoleManager in the App_Start folder.
You should not use Asp.Net Identity as if it was the old simple membership.
Alternatively, check the beta(which means things may change) version of Identity to learn more on how to do in Identity.
Here is how to start :
Create a new project : Choose Empty template (Not MVC not WebForm)
Install the Asp.Net identity sample via nuget
PM> Install-Package Microsoft.AspNet.Identity.Samples -Pre
edit namespace to match your old project namespace
If you want to copy some folders from your old project to the new project, copy your (Controllers, Views,... ) not the config files.
Here you can create roles as follows:
var role = new IdentityRole("roleName");
var roleresult = await RoleManager.CreateAsync(role);
and to create and add a user to specific roles you will use this
var user = new ApplicationUser
{
UserName = "tresorunikin",
Email = "tresorunikin#bellashada.com",
EmailConfirmed =true
};
var userResult = await UserManager.CreateAsync(user, "123#Strong.Password");
if(userResult.Succeeded){
string[] roles =new string[]{"admin","seller","other"};
var roleResult = await UserManager.AddToRolesAsync(user.Id, roles);
if(roleResult.Succeeded){
//Here, user has been added to roles
}
}
All these are done for you by Pranav Rastogi, one of the Identity team at Microsoft.
Note that with these samples you target a new (beta) version of System.Web.Mvc that is newer than System.Web.Mvc 5.0.0.0 If I remember well the beta version is System.Web.MVC 5.0.1.2 or something like that
To Learn More about Identity click here
UPDATES
The Version in the samples is: System.Web.Mvc 5.2.1.0

Related

ASP.NET MVC Exception 'The Role Manager feature has not been enabled'

I'm trying to make an ASP.net MVC website. I have setup Roles in the Startup.cs file as follows:
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("SuperAdmin"))
{
// first we create Admin role
var role = new Microsoft.AspNet.Identity.EntityFramework.IdentityRole();
role.Name = "SuperAdmin";
roleManager.Create(role);
//Here we create a Admin super user who will maintain the website
var user = new ApplicationUser();
user.UserName = "SuperAdmin";
user.Email = "SuperAdmin#SU.com";
string userPWD = "Password1";
var chkUser = UserManager.Create(user, userPWD);
//Add default User to Role Admin
if (chkUser.Succeeded)
{
var result1 = UserManager.AddToRole(user.Id, "SuperAdmin");
}
}
}
I have verified that the above code successfully adds the roles to the db and I first noticed the roles not working when I tried Roles.IsUserInRole(User.Identity.Name, "SuperAdmin")
I'm trying to controll which roles see certain content in a view and am getting an Exception:
System.Configuration.Provider.ProviderException: 'The Role Manager feature has not been enabled.'
when I try to call the following line in a .cshtml file: #Roles.GetRolesForUser();
ive looked where to enable roleManager in Web.config, but cant find it and it dosent work if i add it under the system.web section
EDIT: adding (>roleManager enabled="true"<) into the following code produces another unhandled exception whenever using IsUserInRole: "System.Web.HttpException: Unable to connect to SQL Server database."
<system.web>
<authentication mode="None"/>
<compilation debug="true" targetFramework="4.7"/>
<httpRuntime targetFramework="4.7"/>
</system.web>
i think i might be simply missing a dependancy or some initalizer but have no clue and none of the other solutions in similar quesions have worked.
You can do this by reading from the boolean property at:
System.Web.Security.Roles.Enabled
This is a direct read from the enabled attribute of the roleManager element in the web.config:
<configuration>
<system.web>
<roleManager enabled="true" />
</system.web>
</configuration>
For more information, check out this MSDN sample: https://msdn.microsoft.com/en-us/library/aa354509(v=vs.110).aspx

where is password must have at least one lowercase ['a'-'z'] message in mvc 5

in registration form when user enter just numeric character it shows "password must have at least one lowercase ['a'-'z']", I need to translate it in my native language, where can I find this message?
Firstly, install the identity localized package in Package Manager Console:
Install-Package Microsoft.AspNet.Identity.Core.tr
(.tr or your localization code .it, .es, .de, .fr etc.)
Then set culture in web.config:
<system.web>
<globalization culture="tr-TR" uiCulture="tr"/>
</system.web>
Now, your identity messages will be automatically set according to your language.
These messages are provided by framework, not from your model, so you cannot use data annotations for this. But you can solve the problem in another way:
Step 1: Create resource file for your controller or use shared resource. For example, if your controller is /Controllers/AccountController.cs, then resource file should be Controllers.AccountController.de.resx in your resources folder (depending on configuration; instead of de use your locale code).
Step 2: Write translations for strings: PasswordRequiresLower, PasswordRequiresNonAlphanumeric, PasswordRequiresUpper. These strings are codes of identity errors. You can see them during debug of registration process after failed registration.
Step 3: Do not forget to use localizer in your controller
using Microsoft.Extensions.Localization;
public class AccountController : Controller
{
private readonly IStringLocalizer<AccountController> _localizer;
public AccountController(IStringLocalizer<AccountController> localizer)
{
_localizer = localizer;
}
// Another code of AccountController class.
}
Step 4: Add translated descriptions for errors in registration action
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
// User account created.
return RedirectToAction("Index", "Home");
}
// User account creation failed.
foreach (var error in result.Errors)
{
ModelState.AddModelError(error.Code, _localizer[error.Code]);
}

UserManager doesn't recover stored Roles from user ( Identity 2.1 ASP MVC 5)

The roles stored in the database are not recovered by UserManager.GetRoles(userId);
I have use Identity before and never happend this... don't know what I have done this time or what's happening...
How I create user and his role:
var result = manager.Create(applicationUser, model.Password);
if (result.Succeeded)
{
var userRegistered = manager.FindByName(applicationUser.UserName);
var roleResult = manager.AddToRole(userRegistered.Id, model.Rol);
if(roleResult.Succeeded){return true;}
}
This return true and data store on db tables ( user, and userRole) but..
When I login I can't access to actions... with role authorization...
[Authorize(Roles = "Admin")]
public ActionResult Delete(string id)
On debug I have checked that user have no items on Roles list !!!
Posts I've seen haven't helped me solve the problem , any idea why it does not work ?
Im working with Identity 2.1 ASP MVC 5 on VS 2013comm
Thanks for your help ;)

Can a forms authentication cookie .ASPXAUTH be used to assign a user to a MVC 5 OWIN application's context?

Can a .ASPXAUTH forms authentication cookie be used in an MVC 5 OWIN-based application to create a user in the HttpContext.User property?
Both applications share the same machineKey and the domain/server are the same. The .ASPXAUTH cookie is also available in the MVC 5 application's OwinContext.Request.Cookies collection.
In MVC 5 OWIN-based project:
You should think about several things.
That's how it works for me:
Do all things described in this article (see also github project)
Dont forget set up "compatibilityMode" for machineKey tag in web.config in BOTH projects
for example <machineKey compatibilityMode="Framework20SP1" validationKey="..."/>
validationKey, decryptionKey, validation and description should be the same in both sites.
Then I had rewrite methods Protect
public string Protect(AuthenticationTicket data)
{
var ticket = new FormsAuthenticationTicket(
2, data.Identity.Name,
DateTime.Now, DateTime.Now.AddMinutes(2880), true, "");
var ret = FormsAuthentication.Encrypt(ticket);
return ret;
}
because the ticked described by Alex Yang was "dead" (expired), and Unprotect
public AuthenticationTicket Unprotect(string protectedText)
{
var ticket = FormsAuthentication.Decrypt(protectedText);
var mngr = HttpContext.Current.GetOwinContext()
.GetUserManager<AppUserManager>();
var user = mngr.FindByName(ticket.Name);
var identity = mngr.CreateIdentity(
user, DefaultAuthenticationTypes.ApplicationCookie);
return new AuthenticationTicket(identity, new AuthenticationProperties());
}
because OnValidateIdentity didnt work properly for me and Alex Yang created for output new FormsAuthenticationIdentity, but i needed ClaimsIdentity.
If you want to use version by Alex Yang, dont forget add method used in OnValidateIdentity that he had forgot to describe :) Add it to your AppUser class
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(
UserManager<AppUser> manager)
{
// Note the authenticationType must match the one
// defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity =
await manager.CreateIdentityAsync(this,
DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
After i done that, in both sites .ASPXAUTH cookie was accepted/generated right.

Adding Claims-based authorization to MVC 3

I have an MVC app that I would like to add claims-based authorization to. In the near future we will use ADFS2 for federated identity but for now we will used forms auth locally.
Has anyone seen a tutorial or blog post about the best way to use WIF without an external identity provider?
I have seen the following but it is a year old now and I think there should be an easier solution:
http://geekswithblogs.net/shahed/archive/2010/02/05/137795.aspx
You can use WIF in MVC without an STS.
I used the default MVC2 template, but it should work with MVC 3 too.
You need to:
1- Plug WIF 's SessionAuthenticationModule (web.config)
< add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
2- Wherever you authenticate your users, create a ClaimsPrincipal, add all required claims and then create a SessionSecurityToken. This is the LogOn Action in the AccountController created by MVC:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
var cp = new ClaimsPrincipal();
cp.Identities.Add(new ClaimsIdentity());
IClaimsIdentity ci = (cp.Identity as IClaimsIdentity);
ci.Claims.Add(new Claim(ClaimTypes.Name, model.UserName));
SessionSecurityToken sst = FederatedAuthentication
.SessionAuthenticationModule
.CreateSessionSecurityToken(cp,
"MVC Test",
DateTime.
UtcNow,
DateTime.
UtcNow.
AddHours
(1),
true);
FederatedAuthentication.SessionAuthenticationModule.CookieHandler.RequireSsl = false;
FederatedAuthentication.SessionAuthenticationModule.AuthenticateSessionSecurityToken(sst, true);
//FormsService.SignIn(model.UserName, model.RememberMe);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
I just added the required lines and left everything else the same. So some refactoring might be required.
From there on, your app will now receive a ClaimsPrincipal. All automatically handled by WIF.
The CookieHandler.RequiresSsl = false is only because it's a dev machine and I'm not deploying on IIS. It can be defined in configuration too.
WIF is designed to use a STS so if you don't want to do that, then you essentially have to re-invent the wheel as per the article.
When you move to ADFS, you will pretty much have to re-code everything.
Alternatively, have a look at StarterSTS, This implements the same kind of aspnetdb authentication that you need but allows WIF to do the heavy lifting. Then when you migrate to ADFS, you simply have to run FedUtil against ADFS and it will all work without any major coding changes.
(BTW, there is a MVC version - a later implementation - here).

Resources