AuthorizeRole="Admin" not working in mvc3 app? - asp.net-mvc

I have membership provider setup in an mvc3 application.
I ported it from the local sql express app_data/aspnetdb.mdf to a local server 2008 instance
(this is currently working fine for logins/etc, and [Authorize] SomeMethod()
I recently added 1 new aspnet_roles ("Admin") and 1 new entry in the aspnet_UsersInRoles assoc. w/my username.
Role Table:
ApplicationId RoleId RoleName LoweredRoleName Description
3F96CA96-CCB3-4780-8038-AF3CCE0BD4F2 9B5B798D-E56E-4144-A12C-7C8945FCB413 Admin admin Administrator
UsersInRoles:
UserId RoleId
58974159-E60E-4185-AD00-F8024C7C5974 9B5B798D-E56E-4144-A12C-7C8945FCB413
Q1: Why does the following code not let me into this controller action?
[Authorize]
[Authorize(Roles = "Admin")] // !!! This is keeping me out...commented out I can get in but I'm set as "Admin" and have tried lower case "admin" as well.
public ActionResult SomeMethod()
{}
Q1a: Is there another a role provider connection string that I have to setup in the web config to get this to work?

Can you please post parts of your web.config regarding membership and role providers. This sounds like your application name isn't set properly.
<roleManager enabled="true">
<providers>
<clear/>
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="Your Application Name here" />
</providers>
</roleManager>
Edit
Your application name isn't set. It needs to be set to something and it must match the application name in your database table: aspnet_Applications
If you web config has applicationName="TestApp" /> then your database table also needs to have TestApp in the aspnet_Applications table

Make sure that your ApplicationId is the same you are probably using a different applicationId, check here for more info

Try the below code in order to pin point your problem :
public ActionResult SomeMethod() {
if (!User.IsInRole("Admin"))
throw new SecurityException("User is not an admin.");
}
If you get an exception, it means that there is problem with your Membership Provider or you're not in admin role or your applicationid was configured different as suggested below.
These are some of the possibilities.

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

How to fix "Cookie not Sent Over SSL (4720)" ASP.NET MVC?

1.The Tester test my ASP.NET MVC website and report "Cookie not Sent Over SSL(4720)" issues.
2.And they provide me to solve this issue by Add <httpCookies httpOnlyCookies="true" requireSSL="true" /> in Web.config and then I followed the instructions.
3.The problem when i run and test my website the Session and TempData is null when change page. The code below is shown how i set Session and TempData.
3.1 I set Session and TempData when user go to "Home/Index".
public class HomeController : Controller
{
public ActionResult Index()
{
TempData["class"] = "A";
TempData.Keep();
Session["status"] = "NO";
return View();
}
}
3.2 When user change page to "Admin/User" i get TempData["class"] and Session["status"] but both is null.
public class AdminController : Controller
{
public ActionResult User()
{
string userclass = TempData["class"] != null ? TempData["class"].ToString() : "";
string userstatus = Session["status"] != null ? Session["status"].ToSring() : "";
UserModel usermodel = new UserModel(userclass, userstatus);
return View(usermodel);
}
}
If i delete <httpCookies httpOnlyCookies="true" requireSSL="true" /> from Web.config and test again it's work. but it's still issue "Cookie not Sent Over SSL (4720)" when tester test this website.
How to fix this problem?
P.S. Sorry for bad english skill.
If you set your cookies to be sent securely over SSL, then you must enable SSL in IIS Express for this to work.
Visual Studio configures all the necessary things (like your server certificate and the settings) when you select the SSL option for the web host.
You'll find here a full tutorial about it.

MVC 6 - How to configure remote database connection for Identity 2 and Entity Framework 6

I've been spinning my wheels on this for awhile now and haven't been able to find anything substantial on the topic.
I've implemented an MVC 6 project that is utilizing the Identity Framework 2 and Entity Framework 6. The application works fine with a local database being used as my identity repository. On the first connection, the Entity Framework creates the identity tables based on my identity model classes. I built it based off of a project from this book. The chapters on using Identity and all of the online samples I find don't cover pointing the entity framework to a remote database.
Here are my connection strings I've experimented with...
Local database connection string. Project works fine.
<add name="IdentityDb" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\IdentityDb.mdf;Integrated Security=True" providerName="System.Data.SqlClient" />
Failed approach 1. I based this off of other connection strings from my other projects. I removed the meta data parameters because when it comes to my understanding, this points to the edmx file but I don't have one since I'm taking a code first approach and letting identity and the entity frameworks build the database. I'm wondering if I'm missing something here because I've always taken a database first approach until now.
<add name="IdentityDb" connectionString="provider=System.Data.SqlClient;provider connection string="data source=****;initial catalog=IdentityTest;Uid=*****;Pwd=*****;integrated security=False;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
Returned exception details. The metadata keyword is missing.
System.ArgumentException: Some required information is missing from the connection string. The 'metadata' keyword is always required.
Failed approach 2. I built an empty Identity.edmx file thinking this must be where all of the metadata is stored and maybe the entity framework will update it and have it's required resources once the app connects to the database the first time.
<add name="IdentityDb" connectionString="metadata=res://*/Identity.csdl|res://*/Identity.ssdl|res://*/Identity.msl;provider=System.Data.SqlClient;provider connection string="data source=****;initial catalog=IdentityTest;Uid=****;Pwd=****;integrated security=False;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
Returned exception detail. The meta data is missing.
System.Data.Entity.Core.MetadataException: Unable to load the specified metadata resource.
Last failed approach. I found a lot of online sources where people simply changed the metadata parameters to "res://*". I'm guessing this is some kind of wildcard that would locate the metadata resources if they existed...
<add name="IdentityDb" connectionString="metadata=res://*;provider=System.Data.SqlClient;provider connection string="data source=****;initial catalog=IdentityTest;Uid=****;Pwd=****;integrated security=False;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
Returned exception details (With a identity.edmx file in the project)
System.NotSupportedException: Model compatibility cannot be checked because the DbContext instance was not created using Code First patterns. DbContext instances created from an ObjectContext or using an EDMX file cannot be checked for compatibility.
Returned exception details (Without an identity.edmx file in the project)
System.ArgumentException: Argument 'xmlReader' is not valid. A minimum of one .ssdl artifact must be supplied
My database context class
public class AppIdentityDbContext : IdentityDbContext<AppUser>
{
public AppIdentityDbContext() : base("name=IdentityDb") { }
static AppIdentityDbContext()
{
// Seeds the database when the schema is first created through the Entity Framework.
Database.SetInitializer<AppIdentityDbContext>(new IdentityDbInit());
}
// OWIN uses this method to create instances of this class when needed.
public static AppIdentityDbContext Create()
{
return new AppIdentityDbContext();
}
public System.Data.Entity.DbSet<UAM.Models.Identity.AppRole> IdentityRoles { get; set; }
}
// Seed class for initially populating the identity database.
public class IdentityDbInit : DropCreateDatabaseIfModelChanges<AppIdentityDbContext>
{
protected override void Seed(AppIdentityDbContext context)
{
PerformInitialSetup(context);
base.Seed(context);
}
public void PerformInitialSetup(AppIdentityDbContext context)
{
// Initial database configuration
}
}
Any help or insight would be much appreciated. What is the correct approach for doing this? Is there something that I need to do when I transition from using a local database to a remote one? Let me know if I should provide anymore code samples. I'm fairly new to MVC and am currently building this module so that I can use it for a few enterprise applications that I'll be developing this year.
You need to specify providerName="System.Data.SqlClient" instead of providerName="System.Data.EntityClient"
For Example
<add name="IdentityDb" connectionString="Data Source=*******;Database=IdentityTest;Integrated Security=false;User ID=**;Password=******;" providerName="System.Data.SqlClient"/>
This is the connection string I use and it worked without an issue.
<add name="InventoryEntities"
connectionString="metadata=res://*/Entities.csdl|res://*/Entities.ssdl|res://*/Entities.msl;provider=System.Data.SqlClient;provider connection string="data source=.\sqlinstance;initial catalog=DBName;persist security info=True;user id=UID;password=PWD;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
The tool generated this for me (I didn't need to do anything custom to the connection string) so maybe you can delete and let the too re-add it? (I think it does that)?
Also, you didn't rename the EF files at all did you? If you did, you would have to update the connection string to match.

MVC Movie Project - Multiple Errors

strong textI'm attempting to run the MVC Movie Project, located here:
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/accessing-your-models-data-from-a-controller
When I attempt to run it, I'm given an error in the MoviesController.cs:
public ActionResult Index()
{
return View(db.Movies.ToList());
}
Which states: Invalid value for key 'attachdbfilename'.
I researched this and discovered some people has success by changing the connectionString "MovieDBContext" value from this:
<add name="MovieDBContext"
connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Movies.mdf;Integrated Security=True"
providerName="System.Data.SqlClient"
/>
to this:
<add name="MovieDBContext"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Movies.mdf;Integrated Security=True"
providerName="System.Data.SqlClient"
/>
That seems to let it run further, but then it errors out again at the same place in MoviesController.cs ...
public ActionResult Index()
{
return View(db.Movies.ToList());
}
with a new error:
"An error occurred while getting provider information from the database. This can be caused by Entity Framework using an incorrect connection string. Check the inner exceptions for details and ensure that the connection string is correct."
I did a search looking for suggestions to what this was, including these posts:
System.Data.Entity.Core.ProviderIncompatible Exception in MVC 5
An unhandled exception occurred during the execution of the current web request, "Не найден указанный модуль"
It would suggest that my "Movies.mdf" file is missing, but when I check the App_Data folder its there. One person suggested recreating LocalDB, I'm not sure what that is or how I'd do that. As you can tell I'm very new to .NET. Any suggestions are very much appreciated. Thank you for reading.

How to delete a SimpleMembership user?

In my ASP.NET MVC app using Forms Authentication (via SimpleMembership), how do I delete a user/account?
The WebSecurity class doesn't expose DeleteUser. On a lark, I tried:
WebSecurity.InitializeDatabaseConnection(
"MyDbConnection", "Users", "Id", "UserName", autoCreateTables: true);
new SimpleMembershipProvider().DeleteUser(userName, true);
but that complains that I haven't initialized the SimpleMembership provider. In any event, I would very much appreciate some sample code that shows how to delete a user. Thanks!
Bob
PussInBoots is absolutely correct, although this always throws a foreign key constraint violation for me if the deleted user has been added to any roles. I'm sure this was inferred by PussInBoots' "//TODO: Add delete logic here" comment, but I will typically clean up role memberships first like this:
[HttpPost]
public ActionResult Delete(string userName, FormCollection collection)
{
try
{
// TODO: Add delete logic here
if (Roles.GetRolesForUser(userName).Count() > 0)
{
Roles.RemoveUserFromRoles(userName, Roles.GetRolesForUser(userName));
}
((SimpleMembershipProvider)Membership.Provider).DeleteAccount(userName); // deletes record from webpages_Membership table
((SimpleMembershipProvider)Membership.Provider).DeleteUser(userName, true); // deletes record from UserProfile table
return RedirectToAction("Index");
}
catch
{
return View(userName);
}
}
You probably need something like this:
//
// GET: /Members/Delete?userName=someuser
public ActionResult Delete(string userName)
{
var user = context.UserProfiles.SingleOrDefault(u => u.UserName == userName);
return View(user);
}
//
// POST: /Members/Delete?userName=someuser
[HttpPost]
public ActionResult Delete(string userName, FormCollection collection)
{
try
{
// TODO: Add delete logic here
((SimpleMembershipProvider)Membership.Provider).DeleteAccount(userName); // deletes record from webpages_Membership table
((SimpleMembershipProvider)Membership.Provider).DeleteUser(userName, true); // deletes record from UserProfile table
return RedirectToAction("Index");
}
catch
{
return View(userName);
}
}
What happens if you just do Membership.DeleteUser(username,true). You might get a little prompt for adding a using directive on Membership. If you have it configured properly, you shouldn't need to be creating new SimpleMembershipProvider instance.
If you create it on the fly like that, you'll need to set connections on that object and configure it programmatically(it has no clue about the connection you created above). Usually people do that in web.config, but if you created the app using the forms authentication template, then you should have that taken care of automatically.
Your provider my have this bug for which is discussed and solved here: Membership.DeleteUser is not deleting all related rows of the user
I was getting the exception System.NotSupportedException from Membership.DeleteUser when running my unit tests. The problem was the app.config had the "DefaultProvider" set to "ClientAuthenticationMembershipProvider", which as you can see here is "not used by this class".
The fix was to update my app.config to match my web.config and properly configure the default provider:
<membership>
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="Crelate.Properties.Settings.DatabaseMembershipServicesConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
Hey just wanted to post this for anyone running into ObjectContext state issues after following PussInBoots example, because I had the same problem...
If you are accessing additional user data you will need to remove that user from the data context using:
context.Users.Remove(user);
Rather than:
((SimpleMembershipProvider)Membership.Provider).DeleteUser(userName, true);
This will keep you EF context up to date and remove the user from the DB.

Resources