Struts2 save locale in a cookie - struts2

I wish to save request locale in browser cookie so that the next time a new user session is created
this 'locale' cookie is read and specific page is displayed.
Need a way to do this in struts2

Struts dosn't have this as build in function.
First you need to save a cookie with JavaScript
document.cookie = "locale_cookie=fa_IR";
Second extend the I18nInterceptor and change getLocaleFromParam. You can add reading from cookie feature hear (you can extend other methods too):
The method should be some think like below:
#Override
getLocaleFromParam () {
//read cookie and find cookie which its name is locale_cookie
Cookie[] cookies = ServletActionContext.getRequest().getCookies();
for (int i = 0; i < cookies.length; i++) {
if( "locale_cookie".equals(cookie.getName()){
return LocalizedTextUtil.localeFromString( cookie.getName());
}
}
..............
//The rest method
}

Related

How to get cookies time and perform autologin

I am working on a DOT NET Core project in which I have to perform the task of auto-login. I have tried several ways but did not find the solution.
[HttpPost]
public async Task<IActionResult> IndexAsync(myLoginModel lm){
if (lm.IsRemember)
{
CookieOptions option = new CookieOptions();
option.Expires = DateTime.Now.AddDays(10);
Response.Cookies.Append("UserEmail", lm.Email, option);
Response.Cookies.Append("UserPassword", lm.Password, option);
Response.Cookies.Append("IsRemember", lm.IsRemember.ToString(), option);
}
}
Now during 10-days if the user opens the website, I want to redirect to the DASHBOARD PAGE Directly.
public IActionResult Index()
{
string IsRemember= Request.Cookies["IsRemember"];
if (IsRemember== "True")
{
lm.Email = Request.Cookies["UserEmail"];
lm.Password = Request.Cookies["UserPassword"];
//Check if user visited the website during 10 days of time then redirect to DASHBOARD PAGE.
}
}
I have tried many ways in which the below code is one of them but did not get the perfect solution.
Tried Way 1
foreach (HttpCookie thisCookie in this.Request.Cookies)
{
if (thisCookie.Expires < DateTime.Now)
{
// expired
}
}
Tried Way 2
if (Request.Cookies["UserEmail"].Expires.ToString() < DateTime.Now)
{
}
You can not read the cookies expiration date. Please refer: (c# Asp.net getting Cookie expiration time set in javascript always returns 01.01.0001)
So you need to change your approach like following way.
Add Remember Time in Cookies.
Response.Cookies.Append("RememberTime", DateTime.Now(), option);
And read this RememberTime Cookies value and write your logic for check with as per you requirement day.
if (Convert.ToDateTime(Request.Cookies["RememberTime"]).AddDays(10) > DateTime.Now)

Retain Session Data in .NET Core

I have configured an application to use sessions but I have a concern and I am not sure what else I might need to do.
When the user logs in, I set a Session variable and that works fine. If I choose to 'Remember Me' at login, close the browser and then reopen the website, it remembers the logged in user, but not the other session variable that I set.
The configuration and supporting code is as follows:
Startup.cs
//Configure Services
...
services.AddHttpContextAccessor();
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(60);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
...
//Configure()
app.UseSession();
I set the session at login like this:
var result = await _signInManager.PasswordSignInAsync(Input.UserName, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
HttpContext.Session.SetInt32("SessionVariable", 20);
return LocalRedirect(returnUrl);
}
As stated before, this works fine. If I close the browser and reopen the app, the value is no longer available in the application.
Any guidance is appreciated.
Firstly I don't recommend what you're trying to do. The session cookie has its standard behavior (as by design) so you should follow it (I'm not so sure about the detailed reason because I'm not very good at security aspect).
I believe that you can find some alternative solution such as using local storage on the client or use persistent cookie explicitly.
However because it's possible, I would like to show the way you can achieve it. As long as you explicitly set the expiration time for it, it should still be OK (so instead of being cleared after the browsers closing, it will be cleared on a specific time).
Session has 2 parts to be stored:
the session key is stored as a cookie value.
the session data is stored as in-memory cache on the server side.
What you configure (e.g: IdleTimeout) is just for session data. The session key is set as a response cookie using a separate CookieOptions. This options is built from the SessionOptions.Cookie (a CookieBuilder) which is initialized with a default implementation in which the CookieOptions.Expires will be left as default(DateTimeOffset).
So to override it, you can provide your own implementation of CookieBuilder, like this:
public class ConfigurableExpirationCookieBuilder : CookieBuilder
{
readonly CookieBuilder _defaultSessionCookieBuilder;
public ConfigurableExpirationCookieBuilder(CookieBuilder defaultSessionCookieBuilder)
{
_defaultSessionCookieBuilder = defaultSessionCookieBuilder;
}
public override string Domain { get => _defaultSessionCookieBuilder.Domain; set => _defaultSessionCookieBuilder.Domain = value; }
public override bool HttpOnly { get => _defaultSessionCookieBuilder.HttpOnly; set => _defaultSessionCookieBuilder.HttpOnly = value; }
public override bool IsEssential { get => _defaultSessionCookieBuilder.IsEssential; set => _defaultSessionCookieBuilder.IsEssential = value; }
public override TimeSpan? MaxAge { get => _defaultSessionCookieBuilder.MaxAge; set => _defaultSessionCookieBuilder.MaxAge = value; }
public override string Name { get => _defaultSessionCookieBuilder.Name; set => _defaultSessionCookieBuilder.Name = value; }
public override SameSiteMode SameSite { get => _defaultSessionCookieBuilder.SameSite; set => _defaultSessionCookieBuilder.SameSite = value; }
public override string Path { get => _defaultSessionCookieBuilder.Path; set => _defaultSessionCookieBuilder.Path = value; }
public override CookieSecurePolicy SecurePolicy { get => _defaultSessionCookieBuilder.SecurePolicy; set => _defaultSessionCookieBuilder.SecurePolicy = value; }
}
The default cookie builder is private and init all the default (standard) values in its constructor. So we override all the properties to keep those default values in the custom bookie builder. Of course the Expiration is not overridden, it can be set by your code freely. The default cookie builder lets it as null and protect against changing it like this:
public override TimeSpan? Expiration {
get => null;
set => throw new InvalidOperationException(nameof(Expiration) + " cannot be set for the cookie defined by " + nameof(SessionOptions));
}
Without Expiration being set, the built cookie will be treated as session cookie with standard behaviors.
Now you can configure that Cookie along with your IdleTimeout to achieve your desired behavior:
services.AddSession(options =>
{
var sessionTimeout = TimeSpan.FromMinutes(60);
options.Cookie = new ConfigurableExpirationCookieBuilder(options.Cookie);
//for session key
//NOTE: this is not a sliding timeout like set by IdleTimeout
//the actual expire time will be this added with DateTimeOffset.Now
//at the time the session is established.
options.Cookie.Expiration = sessionTimeout;
//for session data
options.IdleTimeout = sessionTimeout;
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
Finally, I would not recommend this, so please don't try to leave some comments like: if it's not recommended, just don't provide any solutions. I love technical aspects more than trying to follow rules & standards. When it's possible, we can show how it's possible instead of trying to hide it. And actually in some real scenarios, some things cannot always be kept sticking to some strict rule.

show the pdf url to authenticated people on the application

I'm trying to opening the URL that has the pdf document in the new tab. If I click on 1000 anchor tags then it will display the url in new tab like http://sivls100.eskom.co.za:8080/finalnewnrs/Document.do?method=dt&fn=1000.pdf. But if any person has this URL in the network can see the pdf file. I would like to show the pdf file to authenticated users.I did some investigation and found that we can achieve this by setting authenticated user in attribute like setAttribute and get Attribute. I did some code and it works as long as session valid. My session timeout is 30 min.It will not work after 30 min.
Code:
public ActionForward dt(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
Object obj = request.getSession().getAttribute("userDetail");
String target = new String(SUCCESS);
if (obj == null) {
target = new String(FAILURE);
} else {
String filename = request.getParameter("fn");
request.setAttribute("filename", "upload/dt/" + filename);
}
return mapping.findForward(target);
}
Thank you for any help or atleast for the better design.

How to access cookie across MVC views

In my MVC app I am trying to store a cookie in one page response and access it another:
So my /account/register controller has an action that calls a method to store a cookie
public void StoreCookie(Guid pid)
{
var userCookie = new HttpCookie("Userid","B6EAF085-247B-46EB-BB94-79779CA44A14");
Response.Cookies.Remove("Userid");
Response.Cookies.Add(userCookie);
}
After a user registers I can see that the response(/account/register ) contains the cookie: Userid:"B6EAF085-247B-46EB-BB94-79779CA44A14
I now wish to access this cookie from another MVC page view - info/paymentsuccess
I tried assigning the value to Viewbag as
Viewbag.userid = #Response.Cookies["Userid"].value
This returns null
how do I access this cookie from another page/MVC view and store it in Viewbag.userid?
In your account register controller set the cookie:
HttpCookie cookie = this.ControllerContext.HttpContext.Request.Cookies["Userid"];
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
You can retrieve the cookie like so in your post /account/register controller:
if (this.ControllerContext.HttpContext.Request.Cookies.AllKeys.Contains("Userid"))
{
HttpCookie cookie = this.ControllerContext.HttpContext.Request.Cookies["Userid"];
// retrieve cookie data here
}
You can access cookies value in your view using following:
Viewbag.userid = #Request.Cookies["Userid"].value
After registering, do you create a new session? Maybe the cookie is set to the MinValue for Expires, which makes it a session cookie.
Try this:
public void StoreCookie(Guid pid)
{
var userCookie = new HttpCookie("Userid","B6EAF085-247B-46EB-BB94-79779CA44A14");
userCookie.Expires = DateTime.Now.AddDays(1); //...or something that fit your needs
Response.Cookies.Remove("Userid");
Response.Cookies.Add(userCookie);
}

Cookie is not deleted

I am using the following code to set a cookie in my asp.net mvc(C#) application:
public static void SetValue(string key, string value, DateTime expires)
{
var httpContext = new HttpContextWrapper(HttpContext.Current);
_request = httpContext.Request;
_response = httpContext.Response;
HttpCookie cookie = new HttpCookie(key, value) { Expires = expires };
_response.Cookies.Set(cookie);
}
I need to delete the cookies when the user clicks logout. The set cookie is not removing/deleting with Clear/Remove. The code is as below:
public static void Clear()
{
var httpContext = new HttpContextWrapper(HttpContext.Current);
_request = httpContext.Request;
_response = httpContext.Response;
_request.Cookies.Clear();
_response.Cookies.Clear();
}
public static void Remove(string key)
{
var httpContext = new HttpContextWrapper(HttpContext.Current);
_request = httpContext.Request;
_response = httpContext.Response;
if (_request.Cookies[key] != null)
{
_request.Cookies.Remove(key);
}
if (_response.Cookies[key] != null)
{
_response.Cookies.Remove(key);
}
}
I have tried both the above functions, but still the cookie exists when i try to check exist.
public static bool Exists(string key)
{
var httpContext = new HttpContextWrapper(HttpContext.Current);
_request = httpContext.Request;
_response = httpContext.Response;
return _request.Cookies[key] != null;
}
What may be problem here? or whats the thing i need to do to remove/delete the cookie?
Clearing the cookies of the response doesn't instruct the browser to clear the cookie, it merely does not send the cookie back to the browser. To instruct the browser to clear the cookie you need to tell it the cookie has expired, e.g.
public static void Clear(string key)
{
var httpContext = new HttpContextWrapper(HttpContext.Current);
_response = httpContext.Response;
HttpCookie cookie = new HttpCookie(key)
{
Expires = DateTime.Now.AddDays(-1) // or any other time in the past
};
_response.Cookies.Set(cookie);
}
The Cookies collection in the Request and Response objects aren't proxies for the cookies in the browser, they're a set of what cookies the browser sends you and you send back. If you remove a cookie from the request it's entirely server side, and if you have no cookies in the response you're just not going to send any thing back to the client, which won't change the set of cookies in the browser at all.
To delete a cookie, make sure that it is in the response cookie collection, but has an expiration time in the past.
Just to add something else I also pass the value back as null e.g.
public static void RemoveCookie(string cookieName)
{
if (HttpContext.Current.Response.Cookies[cookieName] != null)
{
HttpContext.Current.Response.Cookies[cookieName].Value = null;
HttpContext.Current.Response.Cookies[cookieName].Expires = DateTime.Now.AddMonths(-1);
}
}
The best way to implement this is to use a tool like Reflector and see how the System.Web.Security.FormsAuthentication.SignOut method implements removing the authentication cookie.
In Reflector, open up System.Web and navigate to the FormsAuthentication object and find the SignOut method. Right click on it and select "Disassemble" (Choose your language from the menu).
VB.NET
Public Shared Sub SignOut()
FormsAuthentication.Initialize
Dim current As HttpContext = HttpContext.Current
Dim flag As Boolean = current.CookielessHelper.DoesCookieValueExistInOriginal("F"c)
current.CookielessHelper.SetCookieValue("F"c, Nothing)
If (Not CookielessHelperClass.UseCookieless(current, False, FormsAuthentication.CookieMode) OrElse current.Request.Browser.Cookies) Then
Dim str As String = String.Empty
If (current.Request.Browser.Item("supportsEmptyStringInCookieValue") = "false") Then
str = "NoCookie"
End If
Dim cookie As New HttpCookie(FormsAuthentication.FormsCookieName, str)
cookie.HttpOnly = True
cookie.Path = FormsAuthentication._FormsCookiePath
cookie.Expires = New DateTime(&H7CF, 10, 12)
cookie.Secure = FormsAuthentication._RequireSSL
If (Not FormsAuthentication._CookieDomain Is Nothing) Then
cookie.Domain = FormsAuthentication._CookieDomain
End If
current.Response.Cookies.RemoveCookie(FormsAuthentication.FormsCookieName)
current.Response.Cookies.Add(cookie)
End If
If flag Then
current.Response.Redirect(FormsAuthentication.GetLoginPage(Nothing), False)
End If
End Sub
With the above as an example, I was able to create a common method called RemoveCookie() in a shared assembly, code is below:
VB.NET
''' <summary>
''' Method to remove a cookie
''' </summary>
''' <param name="key">Key</param>
''' <remarks></remarks>
Public Shared Sub RemoveCookie(ByVal key As String)
' Encode key for retrieval and remove cookie
With HttpContext.Current
Dim cookie As New HttpCookie(.Server.UrlEncode(key))
If Not IsNothing(cookie) Then
With cookie
.HttpOnly = True
.Expires = New DateTime(&H7CF, 10, 12)
End With
' Remove from server (has no effect on client)
.Response.Cookies.Remove(.Server.UrlEncode(key))
' Add expired cookie to client, effectively removing it
.Response.Cookies.Add(cookie)
End If
End With
End Sub
Having tested this using FireBug and the Cookie add-in for FireBug (in FireFox), I can attest that the cookie immediately gets removed.
Any questions, feel free to message me.
After playing around with this for some time and trying all of the other answers here I discovered that none of the answers here are totally correct.
The part that is correct is that you have to send an expired cookie to effect the deletion. The part that nobody else picked up on (but is demonstrated in the Microsoft code posted by Ed DeGagne) is that the cookie options for the deletion must match exactly the cookie options that were used to set the cookie in the first place.
For example if you originally created the cookie with the HttpOnly option then you must also set this option when deleting the cookie. I expect the exact behavior will vary across browsers and probably over time, so the only safe option that will work long-term is to make sure that all of the cookie options in the deletion response match exactly the cookie options used to create the cookie originally.
Response.Cookies["key"].Expires= DateTime.Now;

Resources