cross site request forgery - in .net using web forms in vs2013 - asp.net

With the auto generated code for VS 2013 for web forms, it adds CSRF protection. Do I need to do anything else to get it to work?
It says the token is added to Page.ViewStateUserKey. How am I suppose to check the ViewState? The debugger says it's null.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication12
{
public partial class SiteMaster : MasterPage
{
private const string AntiXsrfTokenKey = "__AntiXsrfToken";
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
private string _antiXsrfTokenValue;
protected void Page_Init(object sender, EventArgs e)
{
// The code below helps to protect against XSRF attacks
var requestCookie = Request.Cookies[AntiXsrfTokenKey];
Guid requestCookieGuidValue;
if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
{
// Use the Anti-XSRF token from the cookie
_antiXsrfTokenValue = requestCookie.Value;
Page.ViewStateUserKey = _antiXsrfTokenValue;
}
else
{
// Generate a new Anti-XSRF token and save to the cookie
_antiXsrfTokenValue = Guid.NewGuid().ToString("N");
Page.ViewStateUserKey = _antiXsrfTokenValue;
var responseCookie = new HttpCookie(AntiXsrfTokenKey)
{
HttpOnly = true,
Value = _antiXsrfTokenValue
};
if (FormsAuthentication.RequireSSL && Request.IsSecureConnection)
{
responseCookie.Secure = true;
}
Response.Cookies.Set(responseCookie);
}
Page.PreLoad += master_Page_PreLoad;
}
protected void master_Page_PreLoad(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Set Anti-XSRF token
ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;
ViewState[AntiXsrfUserNameKey] = Context.User.Identity.Name ?? String.Empty;
}
else
{
// Validate the Anti-XSRF token
if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue
|| (string)ViewState[AntiXsrfUserNameKey] != (Context.User.Identity.Name ?? String.Empty))
{
throw new InvalidOperationException("Validation of Anti-XSRF token failed.");
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
}

I downloaded Asp.net ViewState Helper. And because I was using 4.5 framework uses a different cyprtoscheme, I had to edit the web.config.
I added this:
<system.web>
<machineKey compatibilityMode="Framework20SP1" />
</system.web>
Then I was able use Fiddler and decrypt the View State and confirmed that the XSRF token is added.

Related

ASP.NET Identity AllowOnlyAlphanumericUserNames

Can someone please help me how can i use special characters in ASP.Net identity?
The problem is that my users cannot register with special characters: č,ć,š,ž,đ.
When you try to enter this characters in registration, i get following error:
User name Krešo is invalid, can only contain letters or digits.
Where and how can i change this.
Here is the code:
using Microsoft.AspNet.Identity;
using Microsoft.Owin.Security;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Pages_Account_Register : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnPrijava_Click(object sender, EventArgs e)
{
UserStore<IdentityUser> userStore = new UserStore<IdentityUser>();
userStore.Context.Database.Connection.ConnectionString =
System.Configuration.ConfigurationManager.ConnectionStrings["SeminariConnectionString3"].ConnectionString;
UserManager<IdentityUser> manager = new UserManager<IdentityUser>(userStore);
IdentityUser user = new IdentityUser();
user.UserName = txtKorisnickoIme.Text;
if(txtLozinka.Text == txtPotvrdaLozinke.Text)
{
try
{
IdentityResult result = manager.Create(user, txtLozinka.Text);
if(result.Succeeded)
{
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
var userIdentity = manager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(new AuthenticationProperties(), userIdentity);
Response.Redirect("Pocetna.aspx");
}
else
{
litStatus.Text = result.Errors.FirstOrDefault();
}
}
catch (Exception ex)
{
litStatus.Text = ex.ToString();
}
}
else
{
litStatus.Text = "Lozinke moraju biti identične.";
}
}
}
You should be able to change this behaviour as follows:
var manager = new UserManager<IdentityUser>(userStore); // existing code
var validator = manager.UserValidator as UserValidator<ApplicationUser>;
if (validator != null) validator.AllowOnlyAlphanumericUserNames = false;
Should validator turn out to be null, then debug a little to find the actual type used at runtime.

asp.net - object reference not set to an instance of an object for master page cs file

This is the code to my Master Page cs file. For some reason when I run my default page, I get an error that says "object reference not set to an instance of an object."
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Theming.MasterPages
{
public partial class Main : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string selectedTheme = Page.Theme;
HttpCookie preferredTheme = Request.Cookies.Get("PreferredTheme");
if (preferredTheme != null)
{
selectedTheme = preferredTheme.Value;
}
if (!string.IsNullOrEmpty(selectedTheme))
{
ListItem item = ThemeList.Items.FindByValue(selectedTheme);
if (item != null)
{
item.Selected = true;
}
}
}
switch (Page.Theme.ToLower())
{
case "darkgrey":
Menu1.Visible = false;
TreeView1.Visible = true;
break;
default:
Menu1.Visible = true;
TreeView1.Visible = false;
break;
}
}
protected void ThemeList_SelectedIndexChanged(object sender, EventArgs e)
{
HttpCookie preferredTheme = new HttpCookie("PreferredTheme");
preferredTheme.Expires = DateTime.Now.AddMonths(3);
preferredTheme.Value = ThemeList.SelectedValue;
Response.Cookies.Add(preferredTheme);
Response.Redirect(Request.Url.ToString());
}
}
}
The error appears to be at the switch statement but I can't figure out why. I've read on other posts that the value is assigning to the variable as null but I don't know why; I've got dark grey as an app theme. If anyone could please help me it would be very much appreciated.
I don't see Menu1 or TreeView1 defined anywhere in your markup. If those are in a content page, you can't access those in the MasterPage code-behind (there may be a way, but you can't directly access them the way you're trying to).

Request Cookies in .net

I need to read with Request the value of cookie in .net page.
This cookie is created with Response before with asp classic 3.
I tried in asp classic 3:
<%
Response.Write(Request.Cookies("PRBT"))
%>
and the cookie is valorized and output is correct.
But if i try in the .net page the cookie value in debug is null, why?
My code below.
Any help would be appreciated, thanks in advance.
using System.Web;
HttpCookie PRBT;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
PRBT = Request.Cookies["PRBT"];
if (HttpContext.Current.Request.Cookies["PRBT"] != null)
{
Response.Write("<p>" + PRBT.ToString());
}
}
}
EDIT 1
using System.Web;
HttpCookie PRBT;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
PRBT = new HttpCookie("PRBT");
PRBT = Request.Cookies["PRBT"];
if (HttpContext.Current.Request.Cookies["PRBT"] != null)
{
Response.Write("<p>" + Server.UrlDecode(PRBT.ToString()));
}
}
}
To add a cookies you should use
HttpCookie cookie=HttpCookie("MyCookie", "MyValue")
Response.Cookies.Add(cookie);
More detail about cookies
http://www.codeproject.com/Articles/244904/Cookies-in-ASP-NET

How to use PageAsyncTask with WebRequest for multiple requests?

I'm targeting a web service that takes a single string parameter.
On a schedule I want to fire off approximately 100 calls to that web service for 100 values from my database.
To optimise the process I believe I need to do the WebRequest calls asynchronously.
I've come across the code example below on a variety of blogs etc. but can't figure out how to adapt it for my requirement.
How can I wrap up the RegisterAsyncTask inside a foreach loop, parsing through the uri for the WebRequest.Create() that's inside BeginAsyncOperation?
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
public partial class AsyncPageTask : System.Web.UI.Page
{
private WebRequest _request;
protected void Page_Load(object sender, EventArgs e)
{
PageAsyncTask task = new PageAsyncTask(
new BeginEventHandler(BeginAsyncOperation),
new EndEventHandler(EndAsyncOperation),
new EndEventHandler(TimeoutAsyncOperation),
null
);
RegisterAsyncTask(task);
}
IAsyncResult BeginAsyncOperation(object sender, EventArgs e,
AsyncCallback cb, object state)
{
_request = WebRequest.Create("http://msdn.microsoft.com");
return _request.BeginGetResponse(cb, state);
}
void EndAsyncOperation(IAsyncResult ar)
{
string text;
using (WebResponse response = _request.EndGetResponse(ar))
{
using (StreamReader reader =
new StreamReader(response.GetResponseStream()))
{
text = reader.ReadToEnd();
}
}
Output.Text = text;
}
void TimeoutAsyncOperation(IAsyncResult ar)
{
Output.Text = "Data temporarily unavailable";
}
}
My intention is to write the response string back into a database. Appreciate this is an additional question but, is there any reason not to include the insert method call within the EndAsyncOperation method ?
This Q&A hints towards my main question but which 4th argument?
First you need to add this to your Web.config file (default is just 2):
<configuration>
<system.net>
<connectionManagement>
<add address="*" maxconnection="100" />
</connectionManagement>
<system.net>
<configuration>
Then you need to add async directive to your page: <%# Page Async="true" %>
protected void Page_Load(object sender, EventArgs e)
{
//...first get UriStringArray from db, and then:
foreach(string uri in UriStringArray)
{
var task = new PageAsyncTask(
new BeginEventHandler(BeginAsyncOperation),
new EndEventHandler(EndAsyncOperation),
new EndEventHandler(TimeoutAsyncOperation),
uri,
true; //run in parallel
);
RegisterAsyncTask(task);
}
}
IAsyncResult BeginAsyncOperation(object sender, EventArgs e, AsyncCallback cb, object state)
{
var request = (HttpWebRequest)WebRequest.Create((string)state);
return request.BeginGetResponse(cb, request);
}
void EndAsyncOperation(IAsyncResult ar)
{
string text;
var request = (HttpWebRequest)ar.State;
using(WebResponse response = request.EndGetResponse(ar))
{
using(StreamReader reader = new StreamReader(response.GetResponseStream()))
text = reader.ReadToEnd();
}
//yes, you can insert in db here, even as a new PageAsyncTask - but then must call ExecuteRegisteredAsyncTasks() manually...
}

asp.net - global.asax in asp.net 2.0 app

I created a global.asax file for an asp.net application. I run some code in the session_start method. The code does not get executed. Is there some type of procedure for using a global.asax file in asp.net 2.0?
I have the asax file itself and also a codebehind file.
Thank you!
Edit:
asax file:
<%# Application Codebehind="Global.asax.cs" Inherits="GrowUp.Global" %>
The code behind file:
using System;
using System.Collections;
using System.ComponentModel;
using System.Web;
using System.Web.SessionState;
namespace Ligdol
{
/// <summary>
/// Summary description for Global.
/// </summary>
public class Global : System.Web.HttpApplication
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
public Global()
{
InitializeComponent();
}
protected void Application_Start(Object sender, EventArgs e)
{
Application["HostName"] = System.Configuration.ConfigurationSettings.AppSettings["HostName"];
Application["counter"] = 1;
}
protected void Session_Start(Object sender, EventArgs e)
{
// Get the count from the application variable
int counter = int.Parse(Application["counter"].ToString());
//Check if a cookie exists.
if(HttpContext.Current.Request.Cookies["ligdolVersion"] != null)
{
//If a cookie exists, we need to redirect the user to the respective site.
if(HttpContext.Current.Request.Cookies["ligdolVersion"].ToString() == "new")
{
Response.StatusCode = 302;
Response.Status = "Moved temporarily";
Response.Redirect("http://beta.ligdol.co.il");
return;
}
else if(HttpContext.Current.Request.Cookies["ligdolVersion"].ToString() == "old")
{
return;
}
}
else if (counter == 40)
{
// If a cookie does not already exist,
//we need to check if the user is to be allowed to continue to the old site
//or be redirected to the new site.
//Note in a file that a user was redirected, so we can get an estimate of how many are being redirected.
System.IO.TextWriter tw = new System.IO.StreamWriter(#"redirect.log");
tw.WriteLine("Redirected to new site.");
tw.Close();
// Reset counter.
Application["counter"] = 1;
//write cookie made to expire in 30 days, by then the experiment will be over (we hope!).
HttpCookie cookie = new HttpCookie("ligdolVersion");
DateTime dtNow = DateTime.Now;
TimeSpan tsSpan = new TimeSpan(30, 0, 0, 0, 0);
cookie.Expires = dtNow + tsSpan;
cookie.Value = "new";
Response.Cookies.Add(cookie);
Response.Redirect("http://beta.ligdol.co.il");
return;
}
else
{
System.IO.TextWriter tw = new System.IO.StreamWriter(#"redirect.log");
tw.WriteLine("Redirected to old site.");
tw.Close();
HttpCookie cookie = new HttpCookie("ligdolVersion");
DateTime dtNow = DateTime.Now;
TimeSpan tsSpan = new TimeSpan(30, 0, 0, 0, 0);
cookie.Expires = dtNow + tsSpan;
cookie.Value = "old";
Response.Cookies.Add(cookie);
return;
}
}
protected void Application_BeginRequest(Object sender, EventArgs e)
{
}
protected void Application_EndRequest(Object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
}
protected void Application_Error(Object sender, EventArgs e)
{
}
protected void Session_End(Object sender, EventArgs e)
{
}
protected void Application_End(Object sender, EventArgs e)
{
}
#region Web Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
}
#endregion
}
}
The issue was the codebehind file. Once I put the code inline inside the asax file, it worked. This might be the only solution for old website projects.

Resources