How to set SimpleMembershipProvider to require unique email? - asp.net-mvc

I started a new MVC 4 application using VS 2012 and I noticed it is recommending the use of SimpleMembershipProvider.
I like the idea and all the goodies of the WebSecurity class (which helps a lot).
I'd like to be able to set the RequiresUniqueEmail property to true the documentation doesn't have a suggestion on how to accomplish that.

Can you add the property requiresUniqueEmail="true" to the
<membership>
<providers>
<add name="SimpleMembershipProvider"
type="whatever your assembly name is"
...
requiresUniqueEmail="true"/>
tag in your web.config? That's how it's done for the default membership provider. I would imagine it would be the same for the Simple version (unless that feature was not implemented).

Related

How to configure ninject bindings for different scenarios?

When I run my MVC 5 site locally, I want to use these ninject bindings. When I run it in production on azure, I want to use those bindings (which are almost the same, except for a couple different bindings).
How should I detect this, and where should this conditional code go?
To prevent you from having to have separate compilations for each environment, you should drive your DI configuration from web.config. This will keep the door open for a compile once, deploy everywhere strategy.
<appSettings>
<add key="UseSpecialDI" value="true" />
</appSettings>
In your DI config:
bool useSpecialDI = ConfigurationManager.AppSettings["UseSpecialDI"].ToLower() == "true";
if (useSpecialDI)
{
// Use "those settings"
}
else
{
// Use "these settings"
}
Much like your DI configuration, it is best to use fine-grained configuration settings that do specific things rather than broad settings that change large swaths of the DI configuration around.

ASP.NET MVC Cannot find user

I have setup an MVC website with Forms Authentication.
Basically, here is the code that has error which says that there is no such user '2010108703' but still, it is logged on (we can see there is a value at User.Identity.Name)
string user = User.Identity.Name;
Roles.AddUserToRole(user, "student");
return View();
Here is my web.config
<roleManager enabled ="true" defaultProvider="DefaultRoleProvider">
<providers>
<add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</roleManager>
so as you can see, we have a value for the current user which is "2010108703"
but when we are trying to add the role, it says, no such user exist.
Is it a bug? why is that so?
Thanks
FormsAuthentication is a separate system from Membership/Roles. You can put anything you want in the cookie and have the user be logged in, that doesn't mean they exist in your database.
You need to check your login code to make sure that it's actually validating the user against the membership database, and that both membership and roles are using the same connection string.
I'm just taking a wild guess.
Since your creating a new ASP.Net MVC, most likely it comes with ASP.Net Identity instead of legacy ASP.Net Membership Provider. FYI: Look at the database tables.
If so, User.Identity IPrincipal object is still available in ASP.Net Identity.
However, Roles object is not available anymore. Instead, you need to call UserManager object.
For example,
var roleResult = await UserManager.AddUserToRolesAsync(user, new []{"student"});

Can I change the FormsAuthentication cookie name in asp.net dynamically?

I want to set FormsAuthentication cookie name dynammically, for example a guid. how can i do that. I can already change it to whatever I want in web.config. I just can't do it in code and dynamically.Please help.
<authentication mode="Forms">
<forms name="myName" loginUrl="~/Account/Login" defaultUrl="~/Admin/admin" cookieless="UseCookies" slidingExpiration="true" timeout="40320"/>
</authentication>
The reason that I want to do this is, i have several instances of my application on the same host and i do not want them to overwrite each other's cookies.
I have been struggling with Cookies with quite a few days. It has been an awesome learning experience.
So wanted to share the possible ways I found & discovered: There are several HACKs to modify Forms Authentication Cookie name:
You can automate the modification of cookie name under Authenticaiton secion of Web.Config file in Application_Start event in Global.asax. Thanks to Ron for sharing this. But I could not guarantee that the user whose identity would be used to run application domain have enough privileges to modify the file on disk or not. Hence I needed an improvised solution, so I devised following.
Thanks to ILSpy for letting me see inside the FormsAuthentication class, and many thanks to Reflection to let me modify the private field of a class. I used following code to modify the cookie name on run-time with following small piece of code and this worked like a charm !!!
protected void Application_Start(Object sender, EventArgs e)
{
// This will enforce that FormsAuthentication class is loaded from configuration settings for the application.
FormsAuthentication.Initialize();
// The new cookie name whatever you need can go here, I needed some value from my application setting to be prefixed so I used it.
string newCookieName = string.Format("{0}.ASPXAUTH", ConfigurationManager.AppSettings["SomeSettingThatIsUniquetoSite"]);
// Modifying underlying baking field that points to FormsAuthentication.FormsCookieName
Type type = typeof(FormsAuthentication);
System.Reflection.FieldInfo field = type.GetField("_FormsName", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
field.SetValue(null, newCookieName);
}
Suggestions, loopholes are requested as this is my first answer on this forum.
You can't do this in code; the property FormsAuthentication.FormsCookieName is readonly. I would use the following configuration in web.config:
<authentication mode="Forms">
<forms configSource="forms.config" />
</authentication>
Then give each instance of the application its own forms.config:
<forms name="CookieNameForThisInstance" />

Most painless multi-tenancy implementation using ASP.NET, NHibernate / Fluent NHibernate

I'm trying to implement multi-tenancy in an ASP.NET MVC application I have, that uses NHibernate. Though I have control over the database for multi-tenancy. I'm trying to figure out the best way to filter our database queries using NHibernate.
I would like to know if there is a painless way where I can append a condition (something like WHERE InstanceID = 1) to every CRUD query to the DB using NHibernate.
I looked at global filters. But I wasn't sure if I'm using it the right way. I tried something like this.
NHibernateSession.GetDefaultSessionFactory().GetCurrentSession()
.EnableFilter("instance-filter").SetParameter("InstanceId", "2");
But it didn't seem to work. Any good example of NHibernate global filters / any good approach of filtering all DB queries with a condition would be highly appreciated.
I've been looking for the same thing for a small project of mine that's still in planning phase. The most complete implementation of using a single database that I came upon is written by Michael Valenty in his blog post: Bolt-on Multi-Tenancy in ASP.NET MVC with Unity and NHibernate: Part II – Commingled Data. He's also using global filters.
Just for the sake of completeness, here are the mappings he used:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<filter-def name="tenant">
<filter-param name="id" type="System.Int32" />
</filter-def>
</hibernate-mapping>
And for each entity:
<class name="User" table="[user]">
<id name="Id" column="user_id">
<generator class="identity" />
</id>
<property name="Username" />
<property name="Email" />
<filter name="tenant" condition="tenant_id = :id" />
</class>
After that, he uses his IoC container of choice to inject the parameter value to instance of ISession.
session.EnableFilter("tenant").SetParameter("id", c.Resolve<Tenant>().Id);
There's also an interceptor to implement - to write the value of current tenant id when saving the entity (OnSave method), and also to check whether the given entity belongs to current tenant when loading the entity by id (OnLoad method). OnLoad override is necessary because tenant filter won't be applied when loading entity by id.

strong-typed profile values in ASP.NET membership (MVC)

I've been using ASP.NET MVC with membership-based login for several years and everything is working fine (it's now MVC3, but membership didn't change since the first version which was MVC1). Now I need to add a value into the profile (just one value, of very seldom use - so it doesn't warrant custom membership provider or custom tables)
I got it working through profile.SetPropertyValue("myprop"), but I would really want to get profile.myprop to work. Is it possible?
I saw some advise to have a custom class MyProfile : ProfileBase and have myprop as a property of that class. For some reason, casting ProfileBase.Create(currentUser.UserName) to MyProfile gives me an error (illegal cast).
Is there an example somewhere of ASP MVC application with Profile, similar to this Old Post by ScottGu?
Joel Spolsky had a great answer to this question on this post. You're basically on the right track.
If you're getting the illegal cast error, its most likely due to a problem in the config file. Make sure this is included; more specifically the <profile defaultProvider="SqlProvider" inherits="YourNamespace.AccountProfile"> section.
<profile defaultProvider="SqlProvider" inherits="YourNamespace.AccountProfile">
<providers>
<clear />
<add name="SqlProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="sqlServerMembership" />
</providers>
</profile>

Resources