I have a filter class with doFilter method. In the doFilter method, I am setting a cookie as follows
HttpServletResponse httpResp=(HttpServletResponse)servletResponse;
Cookie myCookie=new Cookie("test","");
myCookie.setValue("testValue");
myCookie.setPath("/");
myCookie.setDomain(".mydomain.com");
httpResp.addCookie(myCookie);
filterChain.doFilter(servletRequest,servletResponse);
Should this ideally work? Setting a cookie in httpResp(HttpServletResponse) object and then just forwarding servletResponse(ServletResponse) object
Strangely the cookie is set for some clients but for some others the cookie is not set. I have checked the cookie settings on client's browser and it looks ok.
You can use the HttpServletResponseWrapper to enable the filter to control the response over down stream filters or servlets are
https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletResponseWrapper.html
Here is a pretty good explanation of the wrapper: https://stackoverflow.com/a/7047298/1676293
This will work except you need to refactor the code to:
filterChain.doFilter(servletRequest,servletResponse);
HttpServletResponse httpResp=(HttpServletResponse)servletResponse;
Cookie myCookie=new Cookie("test","");
myCookie.setValue("testValue");
myCookie.setPath("/");
myCookie.setDomain(".mydomain.com");
httpResp.addCookie(myCookie);
Add the cookie after the filterChain call so that another filter/servlet cannot do something that conflicts.
Related
I have a Java HTTP Servlet running in Tomcat. I have a filter that is doing some pre-processing on requests. The filter contains some if/else logic.
I want to set a boolean value in my servlet processing code (doGet/doPost) based on which action my filter performed.
What is the correct way to pass this information from my filter to my servlet method? One idea is to update the request via a setAttribute method, but I am not sure if this is the right way.
In your doFilter(ServletRequest request, ServletResponse response, FilterChain chain) method you can use the request object and set an attribute using request.setAttribute method and then get it in your servlet using request.getAttribute.
See docs: http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#setAttribute(java.lang.String, java.lang.Object)
I have an application running on localhost:8080 and it create a cookie with name jsessionid. Now I need to open another tabs for different application which is running on localhost:8090 which also create a cookie with same name that is jsessionid.
I need to access cookie of first application tab in second application tab..
how can I access both cookies... many tried but no luck...
You can write a servlet filter that would run before page gets rendered (in the atlassian-plugin.xml)
<servlet-filter name="My Filter" i18n-name-key="home-page-redirect-filter.name"
key="home-page-redirect-filter" class="mypackage.CookieFilter"
location="before-dispatch" weight="100">
<description key="home-page-redirect-filter.description">Some description</description>
<url-pattern>WHEN_TO_RUN</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</servlet-filter>
and then you can intercept cookies
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
Cookie[] myCookies=request.getCookies();
//do something with cookies
}
Looks like I misread your question. JSESSIONID is an httponly cookie and you won't be able to use document.cookie in the javascript to get it.
Maybe take a look at Jsoup Cookies for HTTPS scraping and Sending POST request with username and password and save session cookie for some ideas.
I'm having a JavaEE Website running on a cloud-platform.
Now I want to use two types of authentications:
Is from an SSO-System, which is well integrated in the platfrom and works very nicely.
Is the problematic part: I want to authorize a user from 1) for the time of a session, and give him access to a more restricted resource.
Some details
I get the user and his data from 1).
The user first has to ask for permission to 2), which can be denyed or granted. A user gets authorization from a service, which is outside of the scope of his servlet.
For this purpose I pass a User-POJO (with the session of this user as a member) to a service.
If the service grants the rights to this user, it will set an attribute to the user session:
userSession.setAttribute("auth", "granted");
To restrict access to that resource I use a Filter:
#WebFilter("/supersecret/*")
public class NiceFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession session = req.getSession();
// check
if (session.getAttribute("auth") != "granted")
// redirect to login
else
chain.doFilter(req, res);
}
//...
While this is currently working, I feel that my solution is very sloppy.
Altering the user-session outside the scope of a servlet seems to be bad practice.
Adding an attribute to the session for security-purposes is probably not a good idea?
I'd rather want to use standard JavaEE-mechanisms, but most of them are already used for auth-method 1), like declaring login-config in the web.xml.
Any ideas for a more robust solution to this problem?
Thanks in advance :)
I have a Java web application deployed on 2 host machines, fronted by a servlet filter. I sent a POST request to the application on one host, which is intercepted by the filter and redirected to the other host:
public void doFilter (ServletRequest request, ServletResponse response,
FilterChain filterChain)
{
...
if(shouldRedirect) {
httpResponse.sendRedirect(redirectLocation);
}
}
On the second machine, the request passes the filter and is handled by a REST API in a Resource class.
#POST
public Response handleRequest(InputStream stream)
{
...
}
The stream object is sent as part of the POST request body. After the redirection, the request body is not sent over and stream is empty. How do I preserve the request body (or at least this part of it) after the redirect?
Thanks.
Another method I found could work is a 307 (Temporary redirect). This preserves the body of the original request, so it works in this case. The 307 redirect has some security implications as detailed here, but there is the benefit of not having the original host acting as a proxy for a blocking HTTP request.
public void doFilter(...)
{
...
httpResponse.setStatus(TEMPORARY_REDIRECT);
httpResponse.setHeader("Location", redirectLocation);
return;
}
I would perform a post to the redirectLocation instead. sendRedirect is telling the client to change its location so you are starting a new HTTP request at that point.
When you perform the redirect you could have the client initiate the original POST request to the new URL.
sendRedirect() re-visits the user's browser and from browser makes a visit to the re-directed url.
having said that, the POST data is available only at the initial host where the first request has been recievied. i.e. filter in this case.
What you can do :
modify your redirect url to include POST data as Request Parameters in GET url
e.g. host2\servlet?param=one¶m2=two
Read more about URL Redirection
I'm using ServletRequestListener to attach to new requests, get a ServletRequest object and extract cookies from it.
I've noticed that only HTTPServletRequest has cookies but I haven't found a connection between those two objects.
Is it okay to use
HttpServletRequest request = ((HttpServletRequest) FacesContext.getCurrentInstance()
.getExternalContext().getRequest());
to retrieve the request while in a RequestInitialized method? (I do want to run on every request)
FYI - This is all done in a JSF 1.2 Application
This is not correct. The FacesContext isn't available in a ServletRequestListener per se. The getCurrentInstance() might return null, leading to NPE's.
If you're running the webapp on a HTTP webserver (and thus not some Portlet webserver for example), you could just cast the ServletRequest to HttpServletRequest.
public void requestInitialized(ServletRequestEvent event) {
HttpServletRequest request = (HttpServletRequest) event.getServletRequest();
// ...
}
Note that a more common practice is to use a Filter for this since you can map this on a fixed URL pattern like *.jsf or even on specific servlets so that it runs only when the FacesServlet runs. You might for example want to skip cookie checks on static resources like CSS/JS/images.
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletRequest request = (HttpServletRequest) req;
// ...
chain.doFilter(req, res);
}
When you happens to be already inside the JSF context (in a managed bean, phaselistener or whatever), you could just use ExternalContext#getRequestCookieMap() to get the cookies.
Map<String, Object> cookies = externalContext.getRequestCookieMap();
// ...
When running JSF on top of Servlet API, the map value is of type javax.servlet.http.Cookie.
Cookie cookie = (Cookie) cookies.get("name");
Yes, you can do that. In Web scenarios, this will always be ok. If you want to be sure, you could do a check for the type first. (Good practice anyway):
if (FacesContext.getCurrentInstance().getExternalContext().getRequest() instanceof HttpServletRequest) {
...
By the way: Why do you have to use FacesContext? From where are you calling this code?