Cross domain session asp mvc in IE and old browsers - asp.net-mvc

Lets say that you have websites http://simple.com and a lot of subdomain, for example: http://first.simple.com, http://second.simple.com, http://last.simple.com.
Lets say that a user goes to last.simple.com and they get authenticated through the normal ASP .NET membership provider.
Then, from that site, they get sent to (redirection, linked, whatever works) site http://last.simple.com, and the intent of site http://first.simple.com was to pass that user to the other site as the status of isAuthenticated, so that the site http://last.simple.com does not ask for the credentials of said user again.
This worked in Chrome, Mozila, Opera(last versions), Safari, but don't worked in IE(all versions) and Opera( < v12.01).
Scheme:
User, address(first.simple.com) -> post query to server, json answer,
if auth - redirect. May be problem in json(need use 'jsonp')?
web.config
<system.web>
<authentication mode="Forms">
<forms name=".ASPXAUTH" protection="All" domain=".simple.com" enableCrossAppRedirects="true" />
</authentication>
</system.web>
SessionService
public void Authenticate(string username)
{
FormsAuthentication.SetAuthCookie(username, false);
var cookie = FormsAuthentication.GetAuthCookie(username, false);
cookie.HttpOnly = true;
cookie.Path = "/";
cookie.Domain = domain;
this.context.Response.AppendCookie(cookie);
}
Global.asax
protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
const string aspSessionid = "ASP.NET_SessionId";
if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)
{
var cookie = Context.Request.Cookies[aspSessionid];
if (cookie != null && Context.Session != null && !string.IsNullOrEmpty(Session.SessionID))
{
Response.Cookies.Add(new HttpCookie(aspSessionid, Session.SessionID) { Domain = domain, Path = "/", Expires = DateTime.Now.AddDays(30) });
}
}
}

Related

How to maintain a Id value throughout my Asp.net MVC application session management

How to maintain a Id value throughout my Asp.net MVC application after login -- Persist ID throughout ASP.NET MVC application?
I tried using session variable like this in login controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LoginPage(UserLogin login)
{
else if (string.Compare(CryptoCode.Hash(login.Password), v.PPassword) == 0)
{
int timeout = login.RememberMe ? 60 : 60; // 525600 min = 1 year
var ticket = new FormsAuthenticationTicket(login.EmailID, login.RememberMe, timeout);
string encrypted = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
cookie.Expires = DateTime.Now.AddMinutes(timeout);
cookie.HttpOnly = true;
Response.Cookies.Add(cookie);
var profile = db.Profile.Where(x => x.UserLoginId == v.UserLoginId).FirstOrDefault();
Session["PId"] = profile.PId;
if (Url.IsLocalUrl(login.ReturnUrl))
{
return Redirect(login.ReturnUrl);
}
else
{
return Redirect("/ProfilePage/fileupload/index");
}
}
In my Another Controller top level
public ActionResult MainPage()
{
if (Session["PId"] != null)
{
Int64 pid = (Int64)System.Web.HttpContext.Current.Session["PId"];
......
......
}
else
{
return View("~/Registration/Registration/loginpage");
}
}
In web.config file
<authentication mode="Forms">
<forms cookieless="UseCookies" loginUrl="~/Registration/loginpage" timeout="60" slidingExpiration="true"></forms>
</authentication>
<sessionState mode="InProc" timeout="60"></sessionState>
when i close browser the session value getting null but my session login is active, so i get null reference exception or pid null.
In my application i have many controllers that have many action methods. i am not interested to check if condition session value in every action method.
How to maintain a session value after browser close and reopen in given timeout in session (like 20 min)?

asp.net mvc form authenticate lose cookie session

asp.net mvc project when publish, it always lose session after 15-20 minutes.
my global.asax
enter code protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
}
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
var authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
if (authTicket != null && !authTicket.Expired)
{
var roles = authTicket.UserData.Split(',');
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles);
}
}
}
Login Method :
//clear any other tickets that are already in the response
Response.Cookies.Clear();
//set the new expiry date - to thirty days from now
DateTime expiryDate = DateTime.Now.AddDays(30);
//create a new forms auth ticket
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(2, login.EmailID, DateTime.Now, expiryDate, true, "Kullanici Bilgisi");
//encrypt the ticket
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
//create a new authentication cookie - and set its expiration date
HttpCookie authenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
authenticationCookie.Expires = ticket.Expiration;
authenticationCookie.HttpOnly = true;
//add the cookie to the response.
Response.Cookies.Add(authenticationCookie);
Please help me. Im control on google developer tools. I see timeout 2018 but session is always losing redirect to login page.
Web Config:
<authentication mode="Forms">
<forms cookieless="UseCookies" loginUrl="~/user/login" slidingExpiration="true"></forms>
</authentication>

FormsAuthentication and Ajax Requests

I have a problem knowing whether a user is authenticated or not when ajax requests are sent from jQuery.
HttpContext.User.Identity is not empty when a user does a regular request from their browser and the aspxauth cookie is set. When a user tries doing a ajax request from jQuery, the aspxauth is not set at all.
My Web.Config
<authentication mode="Forms">
<forms loginUrl="~/" />
</authentication>
Setting the FormsAuthentication Cookie
var cookie = new AuthCookie
{
UserId = user.UserId,
Email = user.Email,
Name = user.Name,
RememberMe = createPersistentCookie,
TimeZone = user.TimeZone,
CompanyId = user.CompanyId,
Roles = new List<string> { user.Role ?? "user" }
};
string userData = JsonConvert.SerializeObject(cookie);
var ticket = new FormsAuthenticationTicket(1, cookie.Email, DateTime.Now,
DateTime.Now.Add(FormsAuthentication.Timeout),
createPersistentCookie, userData);
string encTicket = FormsAuthentication.Encrypt(ticket);
var httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket) { Expires = DateTime.Now.Add(FormsAuthentication.Timeout) };
_httpContext.Response.Cookies.Add(httpCookie);
When I make requests through my broser, the auth cookie appears:
Whenever I make a request through javascript using $.get() or loading javascript scripts / Any other request through javascript, I get:
The odd thing is that on another ASP application I am using WebSecurity and that works perfectly. The auth cookie is always being sent back from client to server. For this ASP MVC 5 application, when I try to use the FormAuthentication, I cannot get the AuthCookie to proceed through all requests.
you are still able to decorate your class/method with [Authorize] and the like. If you're looking to check inside the controller method you have access to the User Property inherited from System.Web.Mvc.Controller or System.Web.Http.ApiController depending on your controller flavor :
//
// Summary:
// Returns the current principal associated with this request.
//
// Returns:
// The current principal associated with this request.
public IPrincipal User { get; set; }
it can be used like so:
if (User != null && User.Identity != null && User.Identity.IsAuthenticated)
{
// user has access - process request
}
Edit:
Here is an example of an [Api]Controller with an ajax[able] method that uses the controller's User property instead of HttpContext's:
public class HelloController : ApiController
{
[HttpGet]
public IHttpActionResult HelloWorld()
{
try
{
if (User != null && User.Identity != null && User.Identity.IsAuthenticated)
{
return Ok("Hello There " + User.Identity.Name + "!");
}
else
{
return Ok("Hello There Anonymous!");
}
}
catch { throw; }
}
}

How to get forms authentication ticket to respecting cookie expiration date

I am having an issue where users of my website login sessions are expiring way before it should.
Here is my login method”
public ActionResult Login(LoginModel model, string returnUrl)
{
var mcookie = new MyCompanyCookie();
if (ModelState.IsValid)
{
using (var myRepo = new MyCompanyRepositry())
{
var passwordHash = MyCompany.Web.Portal.Helpers.Security.CreatePasswordHash(model.Password);
var userAccount = myRepo.GetMyCompanyUser(model.UserName,model.PartnerAccessCode);
if(userAccount != null && userAccount.Password == passwordHash && userAccount.PartnerAccessCode == model.PartnerAccessCode.ToUpper())
{
mcookie.GetMMformsauthentication(userAccount, model.RememberMe);
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", "The user name,access code or password provided is incorrect.");
}
}
And forms authentication ticket:
public void GetMMformsauthentication(UserAccount useraccount, bool createPersistentCookie)
{
const string UnknownUsername = "anonymous";
// Composing UserData to be stored in the auth cookie
var userCookieData = new MarvMentUserCookieData()
{
UserId = useraccount.UserID,
Password = useraccount.Password,
PartnerAccessCode = useraccount.PartnerAccessCode
};
var ticket = new FormsAuthenticationTicket(1, string.IsNullOrEmpty(useraccount.UserID) ? UnknownUsername : useraccount.UserID, DateTime.Now,
DateTime.Now.AddDays(100), createPersistentCookie, userCookieData.ToString(), FormsAuthentication.FormsCookiePath);
var hashedCookie = FormsAuthentication.Encrypt(ticket);
HttpContext.Current.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashedCookie); // Hashed ticket
authCookie.HttpOnly = true;
authCookie.Expires = ticket.Expiration;
authCookie.Path = ticket.CookiePath;
authCookie.Secure = false;
HttpContext.Current.Response.SetCookie(authCookie);
}
}
And expiration settings inmy Web.config
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
Here you can see that the forms expiration settings is set 2880 minutes however users are beign logged out after around 5-10 minutes.
The cookie is set to expire in 100 days
Does anyone have and idea what may be causing this issue?
It looks issue is not with session in authentication tag. Just check what happens if cookies stuff is commented... If Session retained for more time, then focus on cookie stuff.

Session Start and Action Filter for Session Timeout handling

I have a MVC4 application with Windows Authentication. User can type url of any of the 10 views to load the application. There is no specific home page
I need to redirect to a session timeout view if the user was idle for more than a minute. I have kept the session timeout value in config file as one minute. And I have created an action filter to check one particular session value. This particular session value is set in the Session_Start of the Global.asax.
But, when the timeout period is over, the request again hits the Session_Start and it is assigning the value. Hence my action filter is not redirecting to the error view.
What are the possible solutions to overcome this?
Web.Config
<system.web>
<!--Impersonate-->
<identity impersonate="true"/>
<!--Session Mode and Timeout-->
<sessionState mode="InProc" timeout="1" />
<authentication mode="Windows">
</authentication>
<authorization>
<allow users="?" />
</authorization>
</system.web>
Action Filter
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class SessionCheckAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
{
string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower();
HttpSessionStateBase session = filterContext.HttpContext.Session;
var activeSession = session["IsActiveSession"];
if (activeSession == null)
{
//Redirect
var url = new UrlHelper(filterContext.RequestContext);
var loginUrl = url.Content("~/Error/SessionTimeout");
filterContext.HttpContext.Response.Redirect(loginUrl, true);
}
}
}
Global.ASAX
protected void Session_Start(object sender, EventArgs e)
{
Session["IsActiveSession"] = DateTime.Now;
}
Instead of setting a session value and checking it in your action filter, simply check HttpContext.Current.Session.IsNewSession to see if a new session was created for the current request. Modifying your action filter, you would end up with something like this:
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class SessionCheckAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
{
string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower();
HttpSessionStateBase session = filterContext.HttpContext.Session;
if (session.IsNewSession)
{
//Redirect
var url = new UrlHelper(filterContext.RequestContext);
var loginUrl = url.Content("~/Error/SessionTimeout");
filterContext.HttpContext.Response.Redirect(loginUrl, true);
}
}
}
if you want to get fancy and make sure they had a previous session before the new session that was created for this request, you can update the if statement to check if an old session cookie was sent with the request:
string cookieHeader = filterContext.HttpContext.Request.Headers["Cookie"];
if (session.IsNewSession && cookieHeader != null && cookieHeader.IndexOf("ASP.NET_SessionId") >= 0)
{
...
}
But since it looks like you are sending them to a login page, this is probably not something you have to worry about here. If you do use this check, note that this code assumes the default "ASP.NET_SessionId" cookie name; this could be changed in your web.config, in which case you would need to either update the IndexOf parameter with the new cookie name or get the cookie name programmatically.

Resources