Spring redirect with cookies attached - java

Is there a way to set a cookie for a website I'm trying to redirect to? I'm trying to use Spring redirect to achieve this but I think I'm doing something work (or this is not possible at all)
Here's the method I have tried to use:
#GetMapping("/redirect")
public void redirect(HttpServletResponse response) throws IOException {
Cookie testCookie = new Cookie("test-cookie", "blah");
testCookie.setDomain("something.com");
testCookie.setPath("/");
response.addCookie(testCookie);
response.sendRedirect("https://something.com/test.html");
}
I can see the "set-cookie" header but no actual cookie seems to be set in my browser.
M

Encountered same problem. My case was to pass redirect from backend to frontend with attached cookies. Within one main domain. There's no success with code
cookie.path = "/"
cookie.domain = "domain.com"
cookie.maxAge = 60
cookie.isHttpOnly = false
response.addCookie(cookie)
But everything run when I changed to
response.setHeader("Set-Cookie", "customCookie=value; Path=/; Max-Age=60; Domain=domain.com")
Important: cross-domain cookie passing will be blocked by browser

Related

Magnolia headless login

What steps do I need to take to implement user login?
I am using PUR & REST modules. I was able to successfully login using REST endpoint using MgnlContext.login, but if I try to access another endpoint I get 401.
What I have so far:
CredentialsCallbackHandler handler = new PlainTextCallbackHandler(username, password.toCharArray(), "public");
SecuritySupport securitySupport = Components.getComponent( SecuritySupport.class );
LoginResult result = securitySupport.authenticate(handler, SecuritySupportBase.DEFAULT_JAAS_LOGIN_CHAIN);
MgnlContext.login(result.getSubject());
I think I need to get session cookie (that's configured in web.xml) to send with any subsequent request, but where do I get it in the endpoint? And do I need to preserve it myself? Or is it something else entirely?
Both Magnolia and frontend run on localhost, but on different ports.
Magnolia was sending the cookie all the time (as Set-Cookie header), it just never got saved. I had to process it manually for my FE to set the cookie and send it back in every subsequent request.

HttpServletRequest returning no cookies - but they exist

We have a portlet based application that retrieves a certain cookie for validation and then sends off an action request afterwards.
However, we're seeing an issue where the HttpServletRequest is returning a null list of cookies - even though I can 100% confirm there are cookies. In fact, sometimes the code DOES work and shows the cookies (although this is pretty rare).
We've noticed that IE appears to work more frequently than FF and Chrome, but again, there's no consistency or pattern really to determine what causes it to function.
The Request is always obtained - there's never an issue here of a null pointer. The only issue at this moment is that the cookie list is empty.
Method in static class that returns HttpServletRequest
FacesContext context = FacesContext.getCurrentInstance();
Map<String, Object> requests = context.getExternalContext().getRequestMap();
for (String requestName : requests.keySet()) {
if (requests.get(requestName) instanceof HttpServletRequest) {
return ((HttpServletRequest) requests.get(requestName));
}
}
return null;
Call from the other class to the static method above:
Cookie[] cookies = StaticClass.getHttpRequest().getCookies();
System.out.println("Cookies = " + cookies);
The HttpServletRequest method getCookies() should return an array of cookies the client sent in on the request. If the array returned is null, it means that the request the client sent in contains no cookies. Did you call addCookie(yourCookie) method within the same domain or subdomain (I ask as you cannot access cookies across different domains)?
ie:
Cookie yourCookie = new Cookie(name, value);
response.addCookie(yourCookie);
If the cookie was not added to a previous response, it will not be on the request.
Some other clues:
Check your Cookie's max age. Cookie may be expired.
Check the domain of the cookie and the domain of the request URL. If you are not sure, post them here for help.
In general if you can capture the http request message and post it here it will also be helpful.
Update: in firefox you can right click a page, and select 'view page info', then select the 'security' tab, click the 'view cookies' button to view all the cookies. You can also change the domain name in the popup window to see the cookies under other domain.

Grails redirect in controller switching from https to http. Why?

I have a Grails app with some pages only accessible over https and some over http. This is easily handled using a before filter. However when on an https page as soon as a controller does a redirect the user ends up back on http and is directed to https again by the filter.
def update = {
...
redirect(action: "show", id: domainInstance.id)
}
In Firebug I get:
POST ... localhost:8443 (the form submit to controller)
GET ... 302 ... localhost:8080 (the redirect to show in controller)
GET ... 301 ... localhost:8443 (the redirect back to https in filter)
How can I get the controller redirect call to "remember" the current protocol etc.? Or am I doing something else wrong?
I sorted this out by using an after filter to convert the "Location" header in the response to https when needed. The default CachingLinkGenerator is constructed with the http server URL and uses this to create links. So there doesn't seem to be a way to get it to keep the protocol. I also couldn't see any easy way to replace it with my own extended LinkGenerator.
class SecurityFilters {
def filters = {
overall(controller: '*', action: '*') {
after = {
String loc = response.getHeader("Location")
if (isRequiresHttps()) {
response.setHeader("Location", convertToHttps(loc))
}
}
}
}
private boolean isRequiresHttps() { ... }
private String convertToHttps(String url) { ... }
}
It's a bug and appears to be fixed in version 2.0
I would suggest constructing your URL manually and using redirect with that
Manually as in:
def uri = createLink(action: "show", id: domainInstance.id, absolute: false)
redirect(uri: uri)
OR
def url = createLink(action: "show", id: domainInstance.id, absolute: true)
url = url.replace("http:", "https:")
redirect(url: url)
I am not sure how you have configured your grails app to run SSL. Maybe you have configured it transparently in you tomcat server connector?
However, in your code you should not care about SSL or not. Maybe this helps: http://www.juliesoft.com/2010/04/automatic-httphttps-switching-with-grails/

Cookie handling with Servlet

I am having a problem of setting the data of a (persistent/cross browser session) cookie correctly inside a Servlet and the reading it in a Filter.
the code of the Servlet (running at log-in time) is:
String encodedValue = new String(Base64
.encodeBase64(req.getParameter("account").getBytes()));
Cookie cookie = new Cookie("projectAuthenticationCookie", encodedValue );
cookie.setMaxAge(24*60*60);
cookie.setPath("/");
res.addCookie(cookie);
This will get the cookie inside the response, but the when I read it within my filter with the following code:
Cookie authenticationCookie = null;
Cookie[] cookies = ((HttpServletRequest) request).getCookies();
for (Cookie cookie : cookies){
if ("projectAuthenticationCookie".equals(cookie.getName())) {
authenticationCookie = cookie;
}
}
I only get the value I set right, all other fields are either null, empty or different. Max age for example always returns -1 and thus the cookie will never persist.
I tried setting the expires-header with:
res.setDateHeader("Expires", System.currentTimeMillis() + 24*60*60*1000);
as I read that without a valid expires-header the session will timeout anyway (correct me if I am wrong), but that didn't help either...
One issue I am thinking of is that I am running on localhost (tried setting cookie.setDomain("localhost") but also no luck). My web server/serclet container is Jetty 7 but I do not think that this is relevant...
Any hints?
The fields other than name and value are not populated (and thus not meaningful) on cookies you get from a request.
These fields are intended to inform the browser about the max age; path, etc. of the cookie, but the browser doesn't send back this information to the server. The only time where it's important to have the correct max age, path, etc. is when you create a cookie and add it to the response. Use your browser to check if it stores the correct information instead of trying to find it at server-side.

Login via Java Webapp

I already asked this question, but because of missing answers i'll give it another try!
What i want to do
Write a java webapp which logs me, automatically, in any webapp. For an example I chose my zimbra
mailaccount.
How should my Java webapp work
the app should send a login request to the particular app, which is usually corresponding to
the action in the login-form. After executing my app cookies should be set so that I'm logged in
automatically.
What I'm currently trying
I'm using the code below, the doGet() method is part of an extended HttpServlet.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
HttpClient httpclient = new HttpClient();
PostMethod postMethod1 = new PostMethod("http://mail.mydomain.at/zimbra/");
postMethod1.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
postMethod1.addParameter("username", "myname#mydomain.at");
postMethod1.addParameter("password", "mypassword");
postMethod1.addParameter("loginOp", "login");
httpclient.executeMethod(postMethod1);
out.println(postMethod1.getResponseBodyAsString());
}
What's the problem
After executing the code I only get a message, saying that my browser(which is in fact my HttpClient) appears to prohibit cookies.
So what, I think, happens is that the cookies are going to be set in the HttpClient, which I initialized.
But what i want to happen is that the cookies are set in my browser. How can i accomplish this?
SOLUTION:
the quest failed, because by logging in with a webapplication (via a self instantiated HTTPClient), this client receives the cookies, but not the browser. No workaround was found.
I don't think you can set a cookie of www.xyz.com domain if your browser is accessing www.abc.com. Otherwise it would be a big security violation. Anybody could set a fake cookie in their browser and access your data.
In your case you will need to excpilitly login to zimbra from your browser in order to get the cookie set on the client.

Categories

Resources