ASP.NET MVC2 master page and authentication - asp.net

Update: I can't delete this question, because the answer has been upvoted, yet it is not at all the answer to what I'm asking. I'd like to delete this, as it has been a week with no answer, and it's just dragging down my accept %. Thanks.
I have a strongly typed master page that includes information that is based on the currently authenticated user's UserId:
(Guid)Membership.GetUser().ProviderUserKey
Every other normal action/view would require the user to be authenticated prior to it being viewed, which means the user's information is guaranteed to be available.
The problem is, I'm only getting null reference exceptions when I attempt to access the user's info. from the site's master page. I'm guessing this is because there isn't such thing as an [Authorize] attribute that applies to master pages.
Do I have this wrong? Is there another possible cause?
Simple example:
My site's various pages all use a view model object that inherits the master page view model:
<%# Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<Models.MasterViewModel>" %>
the authenticated user object is a property of this base view model. All pages require authentication, so anyone who isn't is redirected to the login view, which has been working flawlessly. So a simple attempt to make use of a user's property in a view is thus:
<%= Model.UserName %>
which I'll put in one of the views, as well as in the site's master view.
When the user is already authenticated, all works as it should, with the UserName being printed twice on the page. When the auth ticket is expired, or a new user comes along however, the page will not redirect to the login, but instead generate an exception that complains of a null reference coming from the <%= Model.UserName %> in the master view.
When I remove the <%= Model.UserName %> from the master view, and leave it in the normal view, it redirects as it should, without throwing the error.
I hope this is somewhat more clear.
Edit:
Maybe someone could offer a better way to access the authenticated user's information in the master page?
Edit #2:
I would be very interested to see any example of an authenticated user's info being accessed in the master page...this is a real head-scratcher for me.
Update:
I haven't accepted the answer because I'm quite familiar with how I can test whether or not a user is authenticated. I am curious to know why no redirection to the login page is taking place.

It's not because of the master page.
Membership.GetUser() will return the current logged-on membership user. If no user is logged in it will return null and that's what is causing your problem.
you can use an if statement in your master page to check if the user is logged in or not before using any user's info.
if(Membership.GetUser() != null )
{
// Use User Info.
}

The only way i manage to reproduce this error is if i add the violating codeblock to a masterpage that is referenced from pages that does not require auth, then look at'em without signing in.
If your masterpage is not used on your logon-page, it could indicate something else is not entirely in place. How's your routing and authentication set up? If your View gets instantiated before the redirect, so will your masterpage, which could provoke this behaviour.

not sure if this still applies in mvc2, but have you tried defining the loginUrl attribute in your web.config?
<authentication mode="Forms">
<forms loginUrl="/user/login" />
</authentication>
<authorization>
<deny users="?" />
</authorization>

Related

Forms Authentication in IE

I have seem a few of these asking the same question but none of the solutions have worked for me thus far so I wanted to see if I am doing something wrong. I have a site that I am using asp.net MVC to create, at current I am using forms authentication to prevent anonymous users from browsing the site. That bit of code is as follows.
<authentication mode="Forms" >
<forms loginUrl="~/login" timeout="15"/>
</authentication>
Then I have a login controller that has the user enter their userName and password then creates an authcookie if the information is accurate.
if (password == encryptedPassword)
{
FormsAuthentication.SetAuthCookie("user", true, model.userName);
}
All of this works in Firefox and Chrome and after the user has logged in he is able to browse the site. However in IE it keeps returning to the log in screen because it keeps recognizing the user as an anonymous user. I checked and the Auth cookie is either never created or doesn't persist as soon as you enter the next page. Some of my attempts to fix this involved using cookieless in the web.config. The only one that works was the one that actually puts the cookie in the URI and we can't have that for the site. Then I tried setting ticketCompatibilityMode="Framework40" but there was no luck there either.
I did see a bug with domain names having non-alpha numerica characters. I currently use the IP to access the domain directly, so I don't know if periods run this problem but even my local host suffers from the same issues. Any input would be appreciated.
Parameters should be in the following order.
FormsAuthentication.SetAuthCookie(model.userName, true, ...);
OR
FormsAuthentication.SetAuthCookie(model.userName, true);
http://msdn.microsoft.com/en-us/library/system.web.security.formsauthentication.setauthcookie.aspx

can I write my Login Page redirect code in Session_End?

Can I write my code in the Session_End method when my session is timeout and I redirect users to the Login Page?
I am using Form Authentication method.
Currently I have create a "CheckSession()" method and calling on each page...
please suggest...
I've always placed the session check code in a master page for webform projects or, more recently, creating a base controller that has this method. Either way the goal is not to duplicate that code everywhere for obvious maintenance reasons.
I think you can manage this through settings in your web.config file without having to use code at all. Just ensure that the duration of your forms authentication cookie and your session are the same length. If your authentication session times out ASP.NET will automatically redirect a user to the login page.
Try:
<forms ... timeout="20" slidingExpiration="true" />
(slidingExpiration is true by default but I've specified it here because it must be true to replicate the timeout behaviour of sessions in ASP.NET)
and:
<sessionState ... timeout="20" />

Google Adwords tracking cookie triggers ASP.NET Request Validation exception

Sorry for my English.
I have a strange problem.
When user click adword link, Google write tracking cookie like that
1813234232.1302674912.30.51.utmgclid=CcgezrsXjagCFcs-zAod_h2oCQ|utmccn=(not set)|utmcmd=(not set)|utmctr= CAA:89 AB0=40#B%20>:
In keyword section(utmctr) there is bad braskets, that cause request validation exception
A potentially dangerous Request.Cookies value was detected from the client (__utmz="...0=40#B%20> at System.Web.HttpRequest.ValidateCookieCollection(HttpCookieCollection cc)
Is there any way to solve this problem without turning off request validation?
Edited
I'm probably found obvious solution: write own request validation module http://jefferytay.wordpress.com/2010/04/15/creating-your-own-custom-request-validation/
By default asp.net validate and check the data for potential attacts.
You can disable this automatic validation by set validateRequest="false" ether on page
<%# Page validateRequest="false" %>
ether on web.config that affect all pages.
<configuration>
<system.web>
<pages validateRequest="false" />
</system.web>
</configuration>
The only think that you need to check by your self after that, is if someone enters any script data to your inputs. Your inputs then need to check out when you render them on the page, and when you enter them on the database.

asp.net forms authentication redirect problem

The default document feature is turned off in IIS and here's the situation...
My start page for my project say is A.aspx. I run the project and sure enough, A.aspx appears in the url of the browser. Like it should though, A.aspx finds no user logged in and redirects to Login.aspx like it should.
A.aspx:
if (Session["UserStuff"] == null)
Response.Redirect("~/Account/Login.aspx");
The login.aspx shows up BUT when the user Logs in, the code:
FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, true);
always redirects to "Default.aspx" and not "A.aspx"
I've examined FormsAuthentication.GetRedirectUrl and sure enough it returns "Default.aspx"
I'm stumped????
In web.config you could set the default page using the defaultUrl attribute:
<authentication mode="Forms">
<forms
loginUrl="login.aspx"
defaultUrl="a.aspx"
protection="All"
timeout="30"
/>
</authentication>
http://www.codeproject.com/KB/aspnet/custom_authentication.aspx Follow this
If you're using FormsAuthentication, your settings should be defined in the web.config. It sounds like you have a default setting in the web.config for DefaultUrl. You shouldn't need the session redirect though. FormsAuthentication should perform this for you. It doesn't hurt to check the session and force a SignOut() if you don't find it, but FormsAuthentication should perform this redirect.
From my understanding, when the user is redirectoed to your login screen, the Forms Authentication mechanism will add the url of the page that the user was originally tring to access, to the login url that that they user tried to access. For example, if you had a login page: http;//bob/login.aspx, and a user tried to access http;//bob/showmethemoney.aspx, then they would get redirected to http;//bob/login.aspx?ReturnUrl=showmethemoney.aspx. So, if you use the ReturnUrl to redirect the user after the user logs in, the user will always be returned to the resource that they were originally trying to get to.

ASP.NET: Authenticating user in code

I'm playing around with authentication and authorization to prepare for some task. I've created two pages: Login.aspx and Default.aspx. In config file i've set authentication to forms and denied unauthenticated users access:
<authentication mode="Forms">
<forms name="aaa" defaultUrl="~/Login.aspx" />
</authentication>
<authorization>
<deny users="?"/>
</authorization>
Then I've written some simple code to authenticate my user in Login.aspx:
protected void Page_Load(object sender, EventArgs e)
{
GenericIdentity identity = new GenericIdentity("aga", "bbb");
Context.User = new GenericPrincipal(identity, new String[] { "User" }); ;
Response.Redirect("~/Default.aspx");
}
When i run it, the redirection doesn't take place. Instead Login.aspx is called over and over because the user is not authenticated (Context.User.Identity.IsAuthenticated is false at every load). What am i doing wrong?
Context.User only sets the principal for the current request. Once the redirect takes place, the current request ends and a new one begins with the non-overridden principal again (which is apparently not authenticated). So, setting Context.User doesn't actually authenticate anything.
Using FormsAuthentication.SetAuthCookie() will set the user's cookie to a valid value accepted by the FormsAuthentication provider, or put the token in the URL. You can redirect to your heart's content because the cookie obviously sticks with the user for future requests.
From MSDN (em added):
With forms authentication, you can use the SetAuthCookie method when you want to authenticate a user but still retain control of the navigation with redirects.
As stated, this does not necessarily require cookies - the name is a little misleading, because it will still work via the URL if FormsAuthentication is in cookieless mode:
The SetAuthCookie method adds a forms-authentication ticket to either the cookies collection, or to the URL if CookiesSupported is false.
Use FormsAuthentication.SetAuthCookie(..). Or FormsAuthentication.RedirectFromLoginPage(..).
You need to actually set the user as authenticated. All of the following methods will work and let you actually get away from your login screen.
FormsAuthentication.Authenticate()
FormsAuthentication.RedirectFromLoginPage()
FormsAuthentication.SetAuthCookie()
Lots of ways to get to the same result.
You need to actually make a call to the formsAuthentication provider to set the login.
FormsAuthentication.RedirectFromLoginPage(txtUser.Text, chkPersistLogin.Checked)
is a simple example
After creating the dummy Context.User, you need to perform a FormsAuthentication.SetAuthCookie or RedirectFromLoginPage method.

Resources