securing view state using ViewstateUserKey property - c#

On reading about preventing cross-site request forgeries in webforms many authors use statements like this:
To use the ViewStateUserKey property within the Viewstate to protect against spoofed post backs. Add the following in the OnInit virtual method of the Page-derived class (This property must be set in the Page.Init event).
protected override OnInit(EventArgs e) {
base.OnInit(e);
if (User.Identity.IsAuthenticated)
ViewStateUserKey = Session.SessionID; }
The following keys the Viewstate to an individual using a unique value of your choice.
(Page.ViewStateUserKey)
This must be applied in Page_Init because the key has to be provided to ASP.NET before Viewstate is loaded. This option has been available since ASP.NET 1.1
I have tried to put the above one in Base page, where all pages are deriving from that page But I am getting error like OnInit must return value
this is my code
public class BasePage : System.Web.UI.Page
{
protected override OnInit(EventArgs e) {
base.OnInit(e);
if (User.Identity.IsAuthenticated)
ViewStateUserKey = Session.SessionID; }
}
Many thanks in advance

The OnInit declaration is missing the return type void.
protected override void OnInit(EventArgs e)

Related

use session in Web Api 2

I have read that an effective way to use enable session in web api 2 is like so:
protected void Application_PostAuthorizeRequest()
{
System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.ReadOnly);
}
I have also created a class that inherits from AuthorizationFilterAttribute and overrides the OnAuthorization method.
But this event is never called - what am I doing wrong?
You could try creating a HttpModule:
public class WebApiSessionModule : IHttpModule
{
protected virtual void OnPostAuthorizeRequest(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
if (this.IsWebApiRequest(context))
{
context.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.ReadOnly);
}
}
}
You'll need to add this to your web.config in
<system.web>
<httpModules>

How to handle custom security on each page?

This might sound like a stupid question, but I am about to implement a custom security database and framework for a new site. I was wondering how best to handle this.
NOTE: I am NOT using the ASP.NET Membership for this, I am using a custom database and everything custom for user management.
There will be several levels of security, so I am a bit stumped on this without making it too difficult. The only thing I could think of so far is check on EVERY PAGE in the Page_Load if they have the right security:
protected void Page_Load(object sender, EventArgs e)
{
CustomUser user = Session["User"] as CustomUser;
if(user != null && user.CanAccessFeature("TopicModeration"))
{
//initialize page elements
}
else
{
Response.Redirect("Default.aspx?featureDenied=TopicModeration", false);
Context.ApplicationInstance.CompleteRequest();
}
}
That works fine, but if I have dozens of pages that have different restrictions, it can get a bit repetitive. Does anybody have any thoughts on this? Should I inherit from System.Web.Page for each security feature, and use that on the page instead?
Thanks!
May i suggest the following approach:
Create a custom controller class as such:
public class CustomController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
CustomUser user = Session["User"] as CustomUser;
if(user != null && user.CanAccessFeature("TopicModeration"))
{
base.OnActionExecuting(filterContext);
}
else
{
filterContext.Result = new RedirectResult("Default.aspx?featureDenied=TopicModeration", false);
Context.ApplicationInstance.CompleteRequest();
}
}
}
Then you may have your controllers where you want that check to inherit from this controller.
You can create a Base Class and make all master pages (or pages) inherit that class.
Here is an example when a Master Page inherits a class.
Class for all master pages to inherit.
public class PageBase: System.Web.UI.MasterPage
{
protected override void OnLoad(EventArgs e)
{
//Put your security code here...
base.OnLoad(e);
}
}
Here is a Master page inheriting the class above.
public partial class Site1ColMaster : MySite.PageBase
{
protected void Page_Load(object sender, EventArgs e)
{
//Master page
}
}

Accessing context session variables in c#

I have an ASP.NET application and dll which extends IHttpModule. I have used the below method to save the session variables in httpcontext through
public class Handler : IHttpModule,IRequiresSessionState
{
public void Init(HttpApplication httpApp)
{
httpApp.PreRequestHandlerExecute += new EventHandler(PreRequestHandlerExecute);
}
public void PreRequestHandlerExecute(object sender, EventArgs e)
{
var context = ((HttpApplication)sender).Context;
context.Session["myvariable"] = "Gowtham";
}
}
and in my asp.net Default.aspx page I have used code to retrive value as
public partial class _Default : System.Web.UI.Page, IRequiresSessionState
{
protected void Page_Load(object sender, EventArgs e)
{
String token = Context.Session["myvariable"].ToString();
}
}
I am getting error response as
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
In order to ensure whether the variables store in session I have crossed check by following method in class handler after storing the value in session as
string ss = context.Session["myvariable"].ToString();
it well executed and retrieved the value from session.
Why do you need to use Context and not Session directly? From the code I can only assume that you are going to set a value in the Session, and then read the value on page load. Rather than you do something like that, you can do this:
Add a Global Application Class, Right click on your project, Add > New Item, choose Global Application Class, and on that file, insert the following code to initialize the value
protected void Session_Start(object sender, EventArgs e)
{
Session["myvariable"] = "Gowtham";
}
On the Page_Load, you can access by:
if ( Session["myvariable"] != null ) {
String token = Context.Session["myvariable"].ToString();
}
Hope this help..
use System.Web.HttpContext.Current.Session["myvariable"] in both parts

Why might an event not register when it is a part of a 3rd partial file in ASP.NET?

I was trying to add some non-production test code by creating a 3rd partial file in addition to MyPage.aspx and MyPage.aspx.cs and MyPage.aspx.designer.cs. I called my third file MyPage.aspx.TEST.cs
In the partial file MyPage.aspx.TEST.cs, I wrote the following:
protected override void OnInit(EventArgs e)
{
Page.LoadComplete += RunTest;
base.OnInit(e);
}
//Assert.
public void RunTest(object sender, EventArgs e)
{
//Clever assertions
}
The code compiles and I then decompile the code and there it is, I can see the OnInit override and the RunTest method.
But when I execute the page, the event doesn't register, nor run, nor can I set a breakpoint.
I move that code out of the MyPage.aspx.TEST.cs partial class into the MyPage.aspx.cs partial file and the event registers and is executed. Stranger, when I decompile the assembly, and do a diff, the class appears to decompile to the same code.
Possible clues that may be unrelated:
The page uses autoeventwireup="true" (I still get the same behavior if I try to register my event my Page_LoadComplete)
The application is a web application (i.e.uses a proj file)
The partial file does compile (and if I introduce errors into the partial file, it will prevent compilation, so I know for sure that the partial file does get compiled)
I get the same result using different events (PreRender, etc)
This is strange, I just made the same experiment and all the events are being fired, I have the same conditions, web application, autoeventwireup = true
Are you inheriting from another base page?
This is my partial class:
public partial class _Default
{
protected override void OnInit(EventArgs e)
{
this.LoadComplete += RunTest;
this.Load += new EventHandler(_Default_Load);
base.OnInit(e);
}
void _Default_Load(object sender, EventArgs e)
{
//throw new NotImplementedException();
}
void RunTest(object sender, EventArgs e)
{
//throw new NotImplementedException();
}
protected override void OnPreRender(EventArgs e)
{
this.Response.Write("omfgggg");
this.lblMyMessageTest.Text = "omfg2";
base.OnPreRender(e);
}
}
All the events works, if I uncomment the //throw new NotImplementedException(); I get the exception as expected.
Try the following:
Ensure the name of your partial page classes are the same
Try to change Page.LoadComplete += RunTest; to this.LoadComplete += RunTest;
Ensure you are not terminating the response of the page when an exception occurs
If you have a custom HTTP module, try to disable it, it might be interfering with the events somehow

SelectedIndexChanged for DropDownList in ASP.NET firing in the wrong order

I've got the following DropDownList in my code that is firing in the wrong order:
public class MyWebpart : WebPart
{
private DropDownList dropDown = new DropDownList();
private string selectedValue;
public Webpart()
{
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
dropDown.AutoPostBack = true;
dropDown.SelectedIndexChanged += new EventHandler(DropDown_SelectedIndexChanged);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.EnsureChildControls();
}
protected void DropDown_SelectedIndexChanged(Object sender, EventArgs e)
{
selectedValue - dropDown.SelectedValue;
}
protected void override void CreateChildControls()
{
base.CreateChildControls();
// create some stuff here
}
I was expecting when the drop down selection changes, the DropDown_SelectedIndexChanged will get called first, but instead it went through the entire lifecycle going from OnInit, OnLoad, CreateChildControls, then DropDown_SelectedIndexChanged.
Am I missing something? How can I get DropDown_SelectedIndexChanged call first?
You can't change the page lifecycle. What you can do is either check if Page.IsPostBack and do something appropriate only on first load OR you can create a webservice and call that webservice from javascript to execute your selectedindexchanged actions in js rather than posting back the whole page.
Good luck!
This is you will call method
protected void override void CreateChildControls()
{
base.CreateChildControls();
dropDown.SelectedIndexChanged += new EventHandler(DropDown_SelectedIndexChanged);
}
The dropDown.AutoPostBack = true; property triggers a postback which causes it to go through the page lifecycle events.
Your best bet is to put if(!IsPostBack) { } check in at least the OnLoad method to filter out events that you didn't want happening on the postback.
You could write some Javascript function and apply it to the 'onchange' event of the dropdownlist. But you'll need to turn off autopostback and it would happen on the client-side rather than on server.
Posted-back values are not accessible from CreateChildControls(); you must wait until the OnLoad event for the posted back private view state to be loaded into controls.
In the OnInt event call EnsureChildControls(); the posted-back values are then available in the controls in the OnLoad event – note: EnsureChildControls() invokes CreateChildControls().

Categories

Resources