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"});
Related
I am using MVC Actionfilter (Global) to call db to get user data and i try to store that in session.
Coding as mentioned in Dependency Injection in ASP.net Session_Start method.
Everything works fine in local machine.
But in production machine, my filterContext.HttpContext.Session (filterContext being ActionExecutingContext) is always null.
I dont know what more information i can give, but if somebody asks questions I am ready to provide more answers.
Please let me know what i can check.
Adding the below to the web.config fixed the problem, although i dont know why it has to be done.
<system.webServer>
<modules>
<remove name="Session" />
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
</modules>
</system.webServer>
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" />
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).
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>
I am trying to keep track of something and using the SessionID as they key to that object
However the SessionID every 2-3 reqiests changes shouldn't it remain the same?
HttpContext.Session.SessionID
Is the code I am using.
I've seen that happen even without MVC. If I remember correctly, ASP.NET keeps assigning new session ids until you place something into the Session variable.
You should initialize the Session object within Global.asax.cs.
void Session_Start(object sender, EventArgs e)
{
HttpContext.Current.Session.Add("__MyAppSession", string.Empty);
}
This way the session will not change unless your browser window is closed.
I am working on a .NET MVC cart application and I added
Session["myVar"] = "1234";
to the Page_Load method found in the Default.aspx.cs code. I also added
<%= this.Session.SessionID %>
to the Site.Master footer. I then rebuilt my app and browsed the various pages of my app and the footer displays the same session id for all pages as expected!
If you look the seession ID cookie is not even sent to the browser unless it's used on the server.
So when a page roundtrips there is no current session ID cookie, so a new session ID is created, hence it is random.
This is logical, why bother tying up the app to a session if the session is not in use?
I would look into using TempData to keep track of something.
Try with adding machine key into your web.config:
Online key generator: http://aspnetresources.com/tools/keycreator.aspx
It seems that server resets machine key for client and generates new one with new session id, every few minutes, which is much lower than it should. Don't know if that's bug or feature:)
Also, you can increase your session state timeout, which is i think 20min by default.
I was having the same problem using ASP.NET Web Forms. I just had to add a global.asax file to the solution and the fixed it for me.
Summing up answers from #jrojo and #Maxam above, with what I am using.
I am using AWS DynamoDB as the session store (out of scope of the question a little, but gives sample).
Add package via NUGET:
Install-Package AWS.SessionProvider
Update Web.config to have keys in appSettings:
<add key="AWSAccessKey" value="XXX" />
<add key="AWSSecretKey" value="YYY" />
And session provider to system.web:
<sessionState timeout="20"
mode="Custom"
customProvider="DynamoDBSessionStoreProvider">
<providers>
<add name="DynamoDBSessionStoreProvider"
type="Amazon.SessionProvider.DynamoDBSessionStateStore, AWS.SessionProvider"
AWSProfilesLocation=".aws/credentials"
Table="ASP.NET_SessionState"
Region="us-east-1"
/>
</providers>
</sessionState>
Add anything to session in global.asax on session start:
void Session_Start(object sender, EventArgs e) {
HttpContext.Current.Session.Add("somethingToForceSessionIdToStick", string.Empty);
}
Verify by adding this to razor of any page. Refresh that page, then open an ignito window and see a different session:
#HttpContext.Current.Session.SessionID
BobsYourUncle
please see if you have set the cookie samesite attribute to strict.
remove cookieSameSite="Strict" and check.