Session values not found after redirect - asp.net

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.

Related

How to trigger HttpApplication.ReleaseRequestState Event

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.

Spring MVC Tomcat Disable JSESSIONID

I have a WebApp with Spring MVC , I run it on the web with Tomcat 7 server . On my localhost Tomcat 9 server my WebApp works just fine creating a session due to a class I created .
In each method in my controller and I have there 5 methods most of them ModelAndView methods e.g :
#RequestMapping(value = { "/home" }, method = RequestMethod.GET)
public ModelAndView goHomePage(HttpSession session, #PathVariable String,HttpServletRequest request, ModelMap modelMap) {
.... return ModelAndView object;
}
I have a user check method that checks if user is on the DataBase and in this method I add Session ID to go with each method until session is over.
RequestMapping(value = "/check", method = RequestMethod.POST)
public String check(HttpServletRequest request,User user,BindingResult bindingResult){
request.getSession().setAttribute("sessionId", id);
return "redirect:/home";
}
and in all other methods It takes each time an HttpSession obect as parameter and checks if it contains the attribute "sessionId".
On my LocalHost it works fine , on my webserver it works fine when I use myhostname.com:8080/WAR_FILE_NAME , but when I use the normal way it adds to my URL line some JSESSIONID=123456 number and doesn't give me to go to the other pages the WebApp has .
Could somebody explain why it happend and what can I do to fix it or disable this jsession cause I use my own session tracking .
I checked already here some answers for common cases but non of them works for me .

Cookie not getting created when redirecting?

I have the following in my controller:
public ActionResult Login(string email, string password)
{
/*
some stuff
...
*/
HttpCookie CustomerCookie = new HttpCookie("Customer");
CustomerCookie.Values.Add("FirstName", Customer.FirstName);
CustomerCookie.Values.Add("LastName", Customer.LastName);
CustomerCookie.Values.Add("Email", email);
CustomerCookie.Secure = true;
Response.Cookies.Add(CustomerCookie);
return RedirectToAction("OrderType", "Order");
}
But for some reason when I look for the cookie it is nowhere to be found after the redirect. Based on this question I was assuming that the method above would work.
Can anyone see why my cookie is not being created here?
Some troubleshooting steps I would take:
Remove the redirect and just return an empty view and see if the cookie is there
Do not set Secure to true and see if that's the issue
Force a response flush to see if there's an action filter or something post action execution that's preventing the cookie from being returned in the response
Use fiddler to look at the actual http response for the cookie in case your browser is preventing cookies

Can IIS require SSL client certificates without mapping them to a windows user?

I want to be able to map SSL client certificates to ASP.NET Identity users. I would like IIS to do as much of the work as possible (negotiating the client certificate and perhaps validating that it is signed by a trusted CA), but I don't want IIS to map the certificate to a Windows user. The client certificate is passed through to ASP.NET, where it is inspected and mapped to an ASP.NET Identity user, which is turned into a ClaimsPrincipal.
So far, the only way I have been able to get IIS to pass the client certificate through to ASP.NET is to enable iisClientCertificateMappingAuthentication and set up a many-to-one mapping to a Windows account (which is then never used for anything else.) Is there any way to get IIS to negotiate and pass the certificate through without this configuration step?
You do not have to use the iisClientCertificateMappingAuthentication. The client certificate is accessible in the HttpContext.
var clientCert = HttpContext.Request.ClientCertificate;
Either you enable RequireClientCertificate on the complete site or use a separate login-with-clientcertificate page.
Below is one way of doing this in ASP.NET MVC. Hopefully you can use parts of it to fit your exact situation.
First make sure you are allowed to set the SslFlags in web.config by turning on feature delegation.
Make site accept (but not require) Client Certificates
Set path to login-with-clientcertificate-page where client certificates will be required. In this case a User controller with a CertificateSignin action.
Create a login controller (pseudo-code)
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
[AllowAnonymous()]
public ActionResult CertificateSignIn()
{
//Get certificate
var clientCert = HttpContext.Request.ClientCertificate;
//Validate certificate
if (!clientCert.IsPresent || !clientCert.IsValid)
{
ViewBag.LoginFailedMessage = "The client certificate was not present or did not pass validation";
return View("Index");
}
//Call your "custom" ClientCertificate --> User mapping method.
string userId;
bool myCertificateMappingParsingResult = Helper.MyCertificateMapping(clientCert, out userId);
if (!myCertificateMappingParsingResult)
{
ViewBag.LoginFailedMessage = "Your client certificate did not map correctly";
}
else
{
//Use custom Membersip provider. Password is not needed!
if (Membership.ValidateUser(userId, null))
{
//Create authentication ticket
FormsAuthentication.SetAuthCookie(userId, false);
Response.Redirect("~/");
}
else
{
ViewBag.LoginFailedMessage = "Login failed!";
}
}
return View("Index");
}

ASP.NET: After returning RedirectResult, URL does not update in browser when https is in use

I'm confused about the behavior of RedirectResult - in some cases (with https), the redirect doesn't seem to happen, but something more like a transfer.
If a user tries to access an internal page without being logged in, they are directed to the login page. After logging in, they're directed back to my app, with query string parameter
schema://host:port/myApp?returnUrl=Inspections.mvc/Edit/43523
The code in the HomeController that handles this looks for the redirectUrl, and does this:
if (returnUrl != null)
{
return Redirect(returnUrl);
}
In my dev environment and one QA environment, I see that a redirect response goes back to the browser, which makes another request, as expected.
But in production and another QA environment (both of which use https), the last redirect doesn't happen. The browser continues to show the url
schema://host:port/myApp?returnUrl=Inspections.mvc/Edit/43523
and displays the content that would be returned by the page Inspections.mvc/Edit/43523.
I'm perplexed - is this expected behavior when RedirectResult is used? Is https the relevant difference?
EDIT: Checking traffic, I see that in the environments using https there IS a redirect (301- moved permanently), but it is back to exactly the same address:
schema://host:port/myApp?returnUrl=Inspections.mvc/Edit/43523
This additional information leaves the mystery as puzzling as ever.
Looking at the source code of RedirectResult class you can see that it should do either a 302 or 301 depending on the kind of redirect you want:
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (context.IsChildAction)
{
throw new InvalidOperationException(MvcResources.RedirectAction_CannotRedirectInChildAction);
}
string destinationUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext);
context.Controller.TempData.Keep();
if (Permanent)
{
context.HttpContext.Response.RedirectPermanent(destinationUrl, endResponse: false);
}
else
{
context.HttpContext.Response.Redirect(destinationUrl, endResponse: false);
}
}
It should be working as expected no matter what schema you are using. Did you look at the actual request/response with a http sniffer such as Fiddler?
Maybe your browser is choosing not to update the URL for some reason and the problem is not in the actual redirect/rewrite.

Resources