I'm working with cookies.
I want to delete my asp .net session cookies which are not pointing to the root directory as shown below.
I have updated the path of the cookie using the below piece of code:
public class CookieManager : SessionIDManager, ISessionIDManager
{
void ISessionIDManager.SaveSessionID(HttpContext context, string id, out bool redirected, out bool cookieAdded)
{
base.SaveSessionID(context, id, out redirected, out cookieAdded);
if (cookieAdded)
{
SessionStateSection sessionStateSection = (System.Web.Configuration.SessionStateSection)ConfigurationManager.GetSection("system.web/sessionState");
var cookie = context.Response.Cookies[sessionStateSection.CookieName];
cookie.Path = context.Request.ApplicationPath;
}
}
}
Web.config code :
<sessionState sessionIDManagerType="ANJU.Reports.WebUI.Library.CookieManager" timeout="30" cookieName="DVCookie"/>
I tried deleting this cookie, like how we delete the cookies which are pointing to the root directory but failed to do so.
Similar to ISessionIDManager.SaveSessionID, we also have ISessionIDManager.RemoveSessionID to remove the session cookies.
As per the microsoft document, mentioned in the below link:
https://learn.microsoft.com/en-us/dotnet/api/system.web.sessionstate.sessionidmanager.removesessionid?view=netframework-4.8
We can't directly call this method from our application code.
The SessionStateModule calls the RemoveSessionID method during the ReleaseRequestState event to remove the session identifier from the Cookies collection of the HttpResponse if a new session was created but was not used.
Can you please help me how to trigger this ReleaseRequestState event from my asp.net application?
Every piece of help is much appreciated.
Thank you all in advance.
Related
In the Asp.net MVC Project I am redirecting my users to another page after login.
On the development environment all my session variables return null.
On Production however this works fine and session variables are retrieved correctly.
can some One please explain why all variables are null on the development environment.
[AllowAnonymous]
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl)
{
// Some validations
if (Url.IsLocalUrl(returnUrl))
{
var urlDeCoded = HttpUtility.UrlDecode(returnUrl);
var htmlDecoded = HttpUtility.HtmlDecode(urlDeCoded);
return Redirect(htmlDecoded);
}
}
/// Retreiveing session variables
var vm = SessionData.GetCurrentObject<MembershipWizardViewModel>();
In web.Config I have the same value for sessionState on both Envirnoments i.e. "InProc"
Do you loose your session ?
I think this could be a problem of cookies : session Ids could be kept in cookies, and if you redirect on a Url which is on a different server, cookies are different, so it creates you a new session... with empty variables.
A common mistake is to redirect from "localhost" to "127.0.0.1", even if it is technically the same, it could cause a lot of troubles.
Trying to use form authentication to only allow access to a page once they have logged in via the login page. When I login and attempt the redirect it just redirects me back to the login page.
Web Login Control
protected void WebGenLogin_Authenticate(object sender, AuthenticateEventArgs e)
{
//Verify user against active directory
if (new AD().validate(WebGenLogin.UserName, WebGenLogin.Password))
{
Session["UserAuthentication"] = WebGenLogin.UserName;
Session.Timeout = 30;
FormsAuthentication.RedirectFromLoginPage(WebGenLogin.UserName, WebGenLogin.RememberMeSet);
Response.Redirect("~/WebGen/Gen/Create.aspx");
}
else
{
Session["UserAuthentication"] = "";
Response.Redirect("http://thekickback.com/rickroll/rickroll.php");
}
}
Create.aspx Web.config
<authentication mode="Forms">
<forms defaultUrl="~/WebGen/Gen/Create.aspx" loginUrl="../Login.aspx" slidingExpiration="true" timeout="30" />
</authentication>
Can you try this:
if (new AD().validate(WebGenLogin.UserName, WebGenLogin.Password))
{
Session["UserAuthentication"] = WebGenLogin.UserName;
Session.Timeout = 30;
FormsAuthentication.SetAuthCookie(WebGenLogin.UserName, false);
FormsAuthentication.RedirectFromLoginPage(WebGenLogin.UserName, WebGenLogin.RememberMeSet);
***SNIP***
I don't know what type of object AD() calls into, but you may not be using the default ASP.NET membership functionality. As I recall, the ValidateUser method on the membership class has the side-effect of actually logging the user in if it returns true.
After authenticating the user, you may need to set HttpContext.User to a new IPrincipal representing the user, and then call FormsAuthentication.SetAuthCookie() before redirecting them.
Ok I figured it out. It had nothing to do with my code. I did however remove storing the username in the session.
What I have to do was change the root site on IIS to an application.
Authentication mode line was placed in the root with Login.aspx
Create.aspx was in another folder. I removed the authentication mode from it's Web.config and just put in the deny section and all is working correctly.
The code actually worked. Found it to be an issue with IIS. Needed to turn the entire folder structure into an application rather than other parts of it.
In ASP.NET the FormsAuthenticationModule intercepts any HTTP 401, and returns an HTTP 302 redirection to the login page. This is a pain for AJAX, since you ask for json and get the login page in html, but the status code is HTTP 200.
What is the way of avoid this interception in ASP.NET Web API ?
In ASP.NET MVC4 it is very easy to prevent this interception by ending explicitly the connection:
public class MyMvcAuthFilter:AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest() && !filterContext.IsChildAction)
{
filterContext.Result = new HttpStatusCodeResult(401);
filterContext.HttpContext.Response.StatusCode = 401;
filterContext.HttpContext.Response.SuppressContent = true;
filterContext.HttpContext.Response.End();
}
else
base.HandleUnauthorizedRequest(filterContext);
}
}
But in ASP.NET Web API I cannot end the connection explicitly, so even when I use this code the FormsAuthenticationModule intercepts the response and sends a redirection to the login page:
public class MyWebApiAuth: AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if(actionContext.Request.Headers.Any(h=>h.Key.Equals("X-Requested-With",StringComparison.OrdinalIgnoreCase)))
{
var xhr = actionContext.Request.Headers.Single(h => h.Key.Equals("X-Requested-With", StringComparison.OrdinalIgnoreCase)).Value.First();
if (xhr.Equals("XMLHttpRequest", StringComparison.OrdinalIgnoreCase))
{
// this does not work either
//throw new HttpResponseException(HttpStatusCode.Unauthorized);
actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
return;
}
}
base.HandleUnauthorizedRequest(actionContext);
}
}
What is the way of avoiding this behaviour in ASP.NET Web API? I have been taking a look, and I could not find a way of do it.
Regards.
PS: I cannot believe that this is 2012 and this issue is still on.
In case someone's interested in dealing with the same issue in ASP.NET MVC app using the Authorize attribute:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class Authorize2Attribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAuthenticated)
{
filterContext.Result = new HttpStatusCodeResult((int) HttpStatusCode.Forbidden);
}
else
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
}
base.HandleUnauthorizedRequest(filterContext);
}
}
}
This way browser properly distinguishes between Forbidden and Unauthorized requests..
The release notes for MVC 4 RC imply this has been resolved since the Beta - which are you using?
http://www.asp.net/whitepapers/mvc4-release-notes
Unauthorized requests handled by ASP.NET Web API return 401 Unauthroized: Unauthorized requests handled by ASP.NET Web API now return a standard 401 Unauthorized response instead of redirecting the user agent to a login form so that the response can be handled by an Ajax client.
Looking into the source code for MVC there appears to be an functionality added via SuppressFormsAuthRedirectModule.cs
http://aspnetwebstack.codeplex.com/SourceControl/network/forks/BradWilson/AspNetWebStack/changeset/changes/ae1164a2e339#src%2fSystem.Web.Http.WebHost%2fHttpControllerHandler.cs.
internal static bool GetEnabled(NameValueCollection appSettings)
{
// anything but "false" will return true, which is the default behavior
So it looks this this is enabled by default and RC should fix your issue without any heroics... as a side point it looks like you can disable this new module using AppSettings http://d.hatena.ne.jp/shiba-yan/20120430/1335787815:
<appSettings>
<Add Key = "webapi:EnableSuppressRedirect" value = "false" />
</appSettings>
Edit (example and clarification)
I have now created an example for this approach on GitHub. The new redirection suppression requires that you use the two correct "Authorise" attribute's; MVC Web [System.Web.Mvc.Authorize] and Web API [System.Web.Http.Authorize] in the controllers AND/OR in the global filters Link.
This example does however draw out a limitation of the approach. It appears that the "authorisation" nodes in the web.config will always take priority over MVC routes e.g. config like this will override your rules and still redirect to login:
<system.web>
<authentication mode="Forms">
</authentication>
<authorization>
<deny users="?"/> //will deny anonymous users to all routes including WebApi
</authorization>
</system.web>
Sadly opening this up for some url routes using the Location element doesn't appear to work and the WebApi calls will continue to be intercepted and redirected to login.
Solutions
For MVC applications I am simply suggest removing the config from Web.Config and sticking with Global filters and Attributes in the code.
If you must use the authorisation nodes in Web.Config for MVC or have a Hybrid ASP.NET and WebApi application then #PilotBob - in the comments below - has found that sub folders and multiple Web.Config's can be used to have your cake and eat it.
I was able to get around the deny anonymous setting in web.config by setting the following property:
Request.RequestContext.HttpContext.SkipAuthorization = true;
I do this after some checks against the Request object in the Application_BeginRequest method in Global.asax.cs, like the RawURL property and other header information to make sure the request is accessing an area that I want to allow anonymous access to. I still perform authentication/authorization once the API action is called.
This is supposed to just work. I've read all the articles I could find via google on the topic, tried to copy as much as I could from other articles on both StackOverflow and CodeProject and others, but regardless of what I try - it doesn't work.
I have a silverlight application that runs fine using Windows Authentication.
To get it running under Forms Authentication I've:
Edited the web.config file to enable Forms Authentication (and delete the Windows Authentication configuration):
<authentication mode="Forms">
<forms name=".ASPXAUTH" loginUrl="logon.aspx" defaultUrl="index.aspx" protection="All" path="/" timeout="30" />
</authentication>
Created a standard logon.aspx and logon.aspx.cs code behind page to take a user input name and password, and create a authentication cookie when the logon was successful, and then redirected the user to the root page of the web site, which is a silverlight application:
private void cmdLogin_ServerClick( object sender, System.EventArgs e )
{
if ( ValidateUser( txtUserName.Value, txtUserPass.Value ) )
{
FormsAuthentication.SetAuthCookie(txtUserName.Value, true);
var cookie = FormsAuthentication.GetAuthCookie(txtUserName.Value, true);
cookie.Domain = "mymachine.mydomain.com";
this.Response.AppendCookie(cookie);
string strRedirect;
strRedirect = Request["ReturnUrl"];
if ( strRedirect == null )
strRedirect = "index.aspx";
Response.Redirect( strRedirect, true );
}
}
So the redirect after successfully logging in launches my silverlight application.
However the user is not authenticated when executing the Silverlight startup code:
public App()
{
InitializeComponent();
var webContext = new WebContext();
webContext.Authentication = new FormsAuthentication();
ApplicationLifetimeObjects.Add( webContext );
}
private void ApplicationStartup( object sender, StartupEventArgs e )
{
Resources.Add( "WebContext", WebContext.Current );
// This will automatically authenticate a user when using windows authentication
// or when the user chose "Keep me signed in" on a previous login attempt
WebContext.Current.Authentication.LoadUser(ApplicationUserLoaded, null);
// Show some UI to the user while LoadUser is in progress
InitializeRootVisual();
}
The error occurs in the ApplicationUserLoaded method, which always has its HasError property set to true on entry to the method.
private void ApplicationUserLoaded( LoadUserOperation operation )
{
if((operation != null) && operation.HasError)
{
operation.MarkErrorAsHandled();
HandlerShowWebServiceCallBackError(operation.Error, "Error loading user context.");
return;
}
...
}
The error reported is as follows - from what it appears to me is that the user isn't considered authenticated on entry to the silverlight app, so it is directing the code to try to return the logon page, which is returning data unexpected by the silverlight app:
An exception occurred while attempting to contact the web service.
Please try again, and if the error persists, contact your administrator.
Error details:
Error loading user context.
Exception details:
Load operation failed for query 'GetUser'. The remote server returned an error: NotFound.
Any ideas?
Based on everything I read, this is supposed to be pretty simple and just work - so I'm obviously making a very basic error.
I'm wondering if after I authenticate the user on my logon.aspx web page, I need to somehow pass an authenticated WebContext instance over from the logon page to my silverlight application instead of creating a new instance in the silverlight app startup code - but have no idea how to do that.
Appreciate any or all suggestions.
I suspect the Response.Redirect("...", true);
According to this article you should pass false to keep the session.
Is it possible to get session cookie name in medium trust level? The code below works in full trust, but throws a security exception in medium trust level.
string sessionCookieName = ((SessionStateSection)WebConfigurationManager.GetSection("system.web/sessionState")).CookieName;
You can use HTTP_COOKIE server variable from the Request object, to get the cookie string that was included with the request.
string cookieString = Request.ServerVariables["HTTP_COOKIE"]
If what you want is to obtain the session cookie name from the web.config, why don't you add a simple entry in the appSettings section containing the session cookie name?
<appSettings>
<add key="SessionCookieName" value="__SessionCookieName"/>
<appSetting>
<sessionState cookieName="__SessionCookieName" />
Then you can read the web.config setting value by using the following code:
public static bool SessionCookieName
{
get { return ConfigurationManager.AppSettings["SessionCookieName"]; }
}