I developed a HttpModule for assigning themes to pages during it's PreInit event from Profile of the logged in user. But seems the profile is not initialized at the time i access it. Is there a specific event after which i should access Profile for a user similar to access page cotnrols after Init event. btw i am running on ASP.NET 2.0 and Custom Profile Provider implementation.
public void CurrentPageOnPreInit(object sender, EventArgs e)
{
//Get the page currently requested
Page currentPage = (Page)sender;
//Get the user profile
ProfileCommon userProfile = HttpContext.Current.Profile as ProfileCommon;
//check if user profile has theme set
if (userProfile != null && !string.IsNullOrEmpty(userProfile.Theme))
{
//retrieve from profile
currentPage.Theme = userProfile.Theme;
where the above method executes on PreInit stage of each page on my application.
It needs to initialized in the OnPreInit method of the class.
override void OnPreInit(EventArgs e);
For methods execution follow this link it give brief about when which method will call asp.net life cycle.
Related
I’ve made a handy “user control” for login to my website and it is placed in the site master.
The natural procedure is that the user logs in the web site and he should be announced with a welcome message containing its full name. The full-Name naturally should sits in a session variable created when the user logged on.
There is no doubt that we place the desired code in the “page_load” event and expect it to pass user’s full-name to the right circumstances (here its a label named lblFullName) in order to print/show the welcome message when login button clicked, But the full-name doesn’t passed until the user logs in the website again (for the 2nd times).
Why this problem happens?
Its some part of my code:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["FullName"]==null)
{
//nothing 2 do.
}
else
{
lblFullName.Text = Session["FullName"].ToString();
}
}
You probably set the Session variable in the user control after the Page_Load event has been processed, so that it will not see the user name until the next postback.
In order to update the Label text as soon as the login is validated, you could:
Define an event in the user control
Register an event handler in the main page
Call the event handler as soon as the user has logged in
In the event handler, update the Label text
You could also eliminate the Session variable by passing the user full name in an EventArgs derived class. If you make the following class accessible in the user control and in the main form:
public class StringEventArgs : EventArgs
{
public string Value { get; set; }
public StringEventArgs(string value)
{
Value = value;
}
}
then you can define this event in the user control:
public event EventHandler<StringEventArgs> UserLoggedIn;
In the function where the login is confirmed, you call the event handlers:
private void UserLoginValidation()
{
// Login validation is done here
bool loginSuccessful = ...
if (loginSuccessful && UserLoggedIn != null)
{
UserLoggedIn(this, new StringEventArgs(fullName));
}
}
In the main page, you register the event handler, which updates the Label:
protected void Page_Load(object sender, EventArgs e)
{
loginUserControl1.UserLoggedIn += loginUserControl1_UserLoggedIn;
...
}
private void loginUserControl1_UserLoggedIn(object sender, StringEventArgs e)
{
lblFullName.Text = e.Value;
}
I have a data driven website and the current users Id gets stored in Session["UserId"].So all the data that shows up in almost all the pages is user specific.and when a user is using the site anonymously,it is a different set of results that i show and has nothing to do with the UserId.
My problem is I have to check if the Session["UserId"] is not null at every line where I am using Session["UserId"] and i somehow feel that it is not the right way to do it.
Is there a way where I can check if the Session is not null on page_load? If my session turns out to be null, how do i handle it? the page won't even load at all.
I hope i was able to explain
Instead of check session on every of your pages, put the session control in a base class and make all your pages extends this class. Every time your page inits the Page_Init base method will check if user is authenticated. If it's not authenticated the method will throw an exception that will be catched by Page_Error method. This method will clear session resources and redirect to Default page.
Make a hyerarchical classes for session control:
public class UserSession { }
public class AnonymousSession : UserSession {}
On your Page Logon put the UserId on the session based on logon type:
bool isAnon = GetAnonymous(); // Check form page if login is anonymously
UserSession user;
if(isAnon)
user = new AnonymousSession();
else
user = new UserSession();
Session.Contents.Add("UserId", user);
Set a property in PageBase named Anonymously that tells you if user has entered anonymously, and use it in your pages to set the set results of each of your pages:
public class PageBase: System.Web.Ui.Page
{
// Check here if session type is anonymous
protected bool Anonymously
{
get
{
return (UserSession)Session.Contents["UserId"] is AnonymousSession;
}
}
protected void Page_Init(object Sender,System.EventArgs e)
{
var user = (UserSession)Session.Contents["UserId"];
if (user == null)
{
throw new SessionException();
}
}
protected void Page_Error(object sender, System.EventArgs e)
{
Exception ex = Server.GetLastError();
Server.ClearError();
if(ex is SessionException)
{
Context.Session.Clear();
Context.Session.Abandon();
FormsAuthentication.SignOut();
Server.Transfer("Default.aspx", true);
}
}
}
I have an asp.net web application that performs some license checks before calling up the login page... if the product is not licensed then it navigates to a abc.aspx page with some error details. This license check is an HttpModule which is configured via web.config.
I have an event handler for context authentication. Whenever the abc.aspx page is called, this event is fired multiple times and the page load never happens.
on Init, i use this code to add the event handler
context.AuthenticateRequest += new EventHandler
When i use a html page, this issue does not seem to occur. The issue exists even if i use some other aspx page for example xyz.aspx...
How can stop this authentication to takes place n number of times. I have tried with HttpContext.Current.Response.End(), it stops the infinite calls, but does not load the page, the page appears blank.
Any one has any idea about this issue?
snippet of Global.asax.
<%# Application Language="C#" Inherits="Microsoft.Practices.CompositeWeb.WebClientApplication" %>
<script runat="server">
private static bool _initializedAlready = false;
private static readonly Object s_lock = new Object();
//fires once on asp.net worker process start
protected override void Application_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (_initializedAlready)
{
return;
}
lock (s_lock)
{
if (_initializedAlready)
{
return;
}
//custom initialization code
base.Application_Start(sender, e);
_initializedAlready = true;
}
}
public override void Init()
{
base.Init();
//initialize the license module here....
licenseModule.Init(this);
}
</script>
The init() method of license module
public void Init(HttpApplication context)
{
context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
}
I think the problem is due to the fact that you are authenticating abc.aspx as well.
When you go to a page and the license check fails, it redirects to abc.aspx. Unfortunately, you did not exempt abc.aspx from this check, and it checks itself, and then redirects to itself again and again and again.
What you can do is to only attach the authenticate request event in your Init() method when the page is not "abc.aspx". Something like:
if(!context.Context.Request.RawUrl.Contains("abc.aspx"))
context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
However, if you only want to do this check on the login page, you would be better off putting the authentication check just on the login page code behind.
I have an asp.net webforms project. In there, an "Admin" has the ability to get to a screen to submit a form that will create a new user (CreateUser.aspx).
If that user's permission is changed later to be less than Admin they can't access that screen anymore to create new users. However, if they saved the exact web request to create a new user from when they were an admin, they can replay this and create new users still.
It is not possible for a random person to submit this form though unless they guess an active session id (that is the only thing checked on each form submit).
CreateUser is one of many examples of admin functions. Is the proper solution to this to validate that the user is an admin on each of these different form submits (not sure of a clean way to do this in asp.net)? Or is it acceptable to just expire the session on logout and never reuse session id's? Does asp.net have any other security features built-in to protect against this type of attack?
One way, is to have a base class(Which inturn inherits the class - "page") and all your aspx pages should inherit this base class. so that whenever a aspx page loads, your base pageLoad method is called. In this method you can check the authentication and authorization.
public class BasePage : System.Web.UI.Page
{
public BasePage()
{
this.Load += new EventHandler(BasePage_Load);
}
void BasePage_Load(object sender, EventArgs e)
{
//Check authentication/authorized
//if authenticated/authorized leave it.. If not redirect to error page
}
}
public partial class Forms_CreateUser : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
public partial class Forms_CreateRole : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
User web.config's Authorization settings to restrict access to CreateUser.aspx to users in the admin role: http://support.microsoft.com/kb/316871 (attribute name is roles instead of users).
I have an ASP.NET WebForms page with forms authentication. When users create a login, I use 'remember me' to create the authentication cookie.
What I now want to do is check the time of their last access. But LastLogin time is updated only when the user uses the login control (which they don't need to use when they have the authentication cookie on their machine), and LastActivity control is updated before any of my code runs.
It looks like the only way I can do this is to hook into the application event Application_AuthenticateRequest - right? Or is there some better way to do this?
Thanks!
Yes you will want to hook the FormsAuthenticationModule.Authenticate event. You can do this by adding a module to your web application. See the following sample module code.
public class BasicAuthenticateModule : IHttpModule
{
public BasicAuthenticateModule()
{
}
public void Dispose()
{
}
public void Init(HttpApplication context)
{
foreach (string name in context.Modules.Keys)
{
if (name == ApplicaionModules.FormsAuthentication)
{
FormsAuthenticationModule module = (FormsAuthenticationModule)context.Modules[name];
module.Authenticate += new FormsAuthenticationEventHandler(module_Authenticate);
break;
}
}
}
private void module_Authenticate(object sender, FormsAuthenticationEventArgs e)
{
}
}
Enjoy!
Instead I used the session_start event in Global.asax.
In there I've stored the current and previous session start DateTime's against the user in the DB (moving the current to the previous each time). This gets me the time of a user's previous session.
It might be better to use session_end - but that's not the time the user left the page, it's [timeout] time after their last activity - so this is a fairly good solution.