Create a cookie using HttpServletRequest? - java

I've created a RenderingPlugin, for use in WebSphere Portal, which is invoked serverside before sending markup to client. The plugin loops through all cookies and if 'test' is not found, I'd like to set that cookie.
I know this is possible with a HttpServletResponse but the RenderingPlugin doesn't have access to that object. It only has a HttpServletRequest.
Is there another way to do this?
public class Request implements com.ibm.workplace.wcm.api.plugin.RenderingPlugin {
#Override
public boolean render(RenderingPluginModel rpm) throws RenderingPluginException {
boolean found = false;
HttpServletRequest servletRequest = (HttpServletRequest) rpm.getRequest();
Cookie[] cookie = servletRequest.getCookies();
// loop through cookies
for (int i = 0; i < cookie.length; i++) {
// if test found
if (cookie[i].getName().equals("test")) {
found = true;
}
}
if (!found){
// set cookie here
}
}
}

Did you try using javascript code to set the cookie ?
<script>
document.cookie = "test=1;path=/";
</script>
you send this as part of the content you give to the Writer rpm.getWriter() and it will be executed by the browser.

I had a problem to simulate a cookie, that is only sending in production, in my test environment.
I solve with HttpServletRequestWrapper in a filter.
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
Cookie cookie = new Cookie("Key", "Value");
chain.doFilter(new CustomRequest((HttpServletRequest) request, cookie), response);
}
}
class CustomRequest extends HttpServletRequestWrapper {
private final Cookie cookie;
public CustomRequest(HttpServletRequest request, Cookie cookie) {
super(request);
this.cookie = cookie;
}
#Override
public Cookie[] getCookies() {
//This is a example, get all cookies here and put your with a new Array
return new Cookie[] {cookie};
}
}
This filter is only started in test environment. My class WebConfig take care of this:
#HandlesTypes(WebApplicationInitializer.class)
public class WebConfig implements WebApplicationInitializer

Related

Spring-Boot: Web-Filter for Redirection

I am having a filter. It should redirect to /b if /a is requested.
public class WebFilter extends GenericFilterBean
{
#Override
public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String path = req.getRequestURI ().toString ();
if (path.equals ("/a") == true)
{
System.out.println ("FILTER: a -> b");
res.reset ();
res.resetBuffer();
res.sendRedirect ("b");
}
chain.doFilter (req, res);
}
}
Here is the handler for the content.
#Component
#Controller
#RequestMapping ("/")
public class WebHandler
{
#RequestMapping ("/a")
public String a ()
{
System.out.println ("a");
return "a"; // point to a.jsp
}
#RequestMapping ("/b")
public String b (HttpSession ses)
{
System.out.println ("b");
return "b"; // point to b.jsp
}
}
If I request /a in a browser, then that is the output.
FILTER: a -> b
IN a
IN b
Why is method a called?
I would expect only b because I redirect in doFilter from a to b.
How can I make that happen?
So you are actually doing a redirect although it seems you just want to direct the request to a different controller mapping.
res.sendRedirect ("b");
Just changes the response code to 302 and adds a location field, you will still hit the first controller, which is why you still see a in the logs.
The browser then acknowledges this redirect directive and will send a second request for /b.
One way to achieve what you appear to want would be to create a new Request from the submitted one, and simply override the getRequestUri() method.
#Override
public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String path = req.getRequestURI();
if (path.equals("/a")) {
req = new HttpServletRequestWrapper((HttpServletRequest) request) {
#Override
public String getRequestURI() {
return "/b";
}
};
}
chain.doFilter (req, res);
}
This is then passed to the filter chain and everything continues as though that were the original request

How to pass GenericFilterBean data to WebSecurityConfigurerAdapter in Spring Boot?

I am trying to redirect http to https in my spring boot application using:
http.requiresChannel().anyRequest().requiresSecure();
But I am getting ERR_TOO_MANY_REDIRECTS. The reason for this is that the load balancer converts all the https to http and directs the http to port 8082, therefore the app never seems to see the https.
I tried to fix this by adding isSecure before the http to https redirection, like this in my configuration:
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
//variables
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/css/**", "/js/**", "/admin/**")
.permitAll().anyRequest().authenticated().and()
.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class)
.formLogin().loginPage("/login").permitAll().and()
.logout().logoutSuccessUrl("/");
//hsts
http.headers().httpStrictTransportSecurity()
.includeSubDomains(true).maxAgeInSeconds(31536000);
http.addFilterBefore(new IsSecureFilter(), ChannelProcessingFilter.class);
//https compulsion
if(!isSecureFilter.isSecure()) {
http.requiresChannel().anyRequest().requiresSecure();
}
}
//rest of the code
}
I am trying to use HttpServletRequestWrapper so that I can repeatedly use isSecure in WebSecurityConfiguration above through the IsSecureFilter I have created below, to prevent infinite redirects:
public class RequestWrapper extends HttpServletRequestWrapper {
private boolean isSecure;
public RequestWrapper(HttpServletRequest request) throws IOException
{
//So that other request method behave just like before
super(request);
this.isSecure = request.isSecure();
}
//Use this method to read the request isSecure N times
public boolean isSecure() {
return this.isSecure;
}
}
Below is the filter that I am trying to inject in WebSecurityConfiguration, to use it's isSecure value above :
#Component
public class IsSecureFilter extends GenericFilterBean {
private boolean isSecure;
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = new RequestWrapper((HttpServletRequest) request);
this.isSecure = req.isSecure();
chain.doFilter(req, response);
}
public boolean isSecure() {
return this.isSecure;
}
}
So running the above code and putting example.com/login in the browser does redirect to https://example.com/login, but i am still getting ERR_TOO_MANY_REDIRECTS.
I can't understand what I am doing wrong?
My first thoughts are:
Can I inject the IsSecureFilter in WebSecurityConfiguration to retrieve isSecure?
Am I adding the IsSecureFilter filter in a correct way to the configuration.
Is the wrapper filter relationship defined correctly?
EDIT
1) I changed http.addFilterAfter(new isSecureFilter(), ChannelProcessingFilter.class); to http.addFilterAfter(isSecureFilter, ChannelProcessingFilter.class);, still no effect.
2) I tried changing http.addFilterBefore(isSecureFilter, ChannelProcessingFilter.class); to http.addFilterAfter(isSecureFilter, ChannelProcessingFilter.class); but that still did not change anything.
Here is the solution to resolve this issue. Based on investigation, since 8080 and 8082 are used to identify HTTP traffic and HTTPS traffic, some code are added to check the port number instead "isSecure" to decide whether redirect HTTP request or not. The code is like following:
public class IsSecureFilter extends GenericFilterBean {
private boolean isSecure;
private int port;
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = new RequestWrapper((HttpServletRequest) request);
HttpServletResponse res = (HttpServletResponse) response;
this.isSecure = req.isSecure();
this.port = req.getLocalPort();
System.out.println("[DEBUG] : isSecure FILTER :: " + isSecure);
System.out.println("[DEBUG] : port FILTER :: " + port);
System.out.println("[DEBUG] : URL :: " + req.getRequestURL());
String url = req.getRequestURL().toString().toLowerCase();
if(url.endsWith("/login") && url.startsWith("http:") && port == 8080){
url = url.replace("http:", "https:");
String queries = req.getQueryString();
if (queries == null) {
queries = "";
} else {
queries = "?" + queries;
}
url += queries;
res.sendRedirect(url);
}
else {
chain.doFilter(req, response);
}
}
public boolean isSecure() {
return this.isSecure;
}
public boolean setIsSecure(boolean isSecure) {
return this.isSecure = isSecure;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
and remove http.requiresChannel().anyRequest().requiresSecure() in WebSecurityConfiguration class.

The servlet container, the servlet url pattern and request wrappers

I was working on a project where based on the presence of a particular string in the request URL to a web application, I was trying to modify the URL of the request using a request wrapper.
I learnt that even if I override the getRequestURI, getRequestURL and getServletPath methods in the wrapper and send that wrapper from a filter, the servlet container still uses its own implementation of the ServletRequest interface to figure out which servlet to call.
I believe the container uses the stored variable for the request URI in the implementation class of ServletRequest and doesn't actually call any of the getRequestURI, getRequestURL and getServletPath methods for identifying the servlet to use (matching URL pattern).
Need all your inputs and knowledge to learn more about this topic. Please help me learn this topic better. Thanks..!!
Below are my experimental code and the request comes from the jsp for http://localhost:8080/RequestResponseListenersWebApp/pages/abcd.jsp
The Filter
#WebFilter(filterName = "AllRequestScanFilter", urlPatterns = "/*")
public class AllRequestScanFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
EmployerViewTestBusinessWrapper wrapper = new EmployerViewTestBusinessWrapper(request);
if (request.getRequestURI().contains("abcd.jsp"))
chain.doFilter(wrapper, resp);
else {
chain.doFilter(req, resp);
}
}
public void init(FilterConfig config) throws ServletException {
}
}
The Wrapper
public class EmployerViewTestBusinessWrapper extends HttpServletRequestWrapper {
public EmployerViewTestBusinessWrapper(HttpServletRequest request) {
super(request);
}
#Override
public String getPathTranslated() {
return super.getPathTranslated();
}
#Override
public String getRequestURI() {
String currentPath=pathModified(super.getRequestURI());
return currentPath!=null?currentPath:super.getRequestURI();
}
#Override
public StringBuffer getRequestURL() {
String currentPath=pathModified(super.getRequestURL().toString());
return currentPath!=null?new StringBuffer(currentPath):new StringBuffer(super.getRequestURL());
}
#Override
public String getServletPath() {
String currentPath=pathModified(super.getServletPath());
return currentPath!=null?currentPath:super.getServletPath();
}
private String pathModified(String currentPath){
String returnPath=null;
if(currentPath.contains("pages")){
returnPath=currentPath.replaceFirst("/pages/","/pages/myapp/");
}
return returnPath;
}
}
The Servlet which is never reached
#WebServlet(name = "EmployerViewTestServlet",urlPatterns = "/pages/myapp/*")
public class EmployerViewTestServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path=request.getParameter("path");
}
}
And one more thing. The Filter I have specified here is the first thing in the web app that's called when a request comes in.
I can always check the URL pattern in the filter and forward the request to the desired URL pattern using a RequestDispatcher.
However, in my app there're some Filters that are called for dispatcher type FORWARD and I don't want them to be called when a request has just come from the client.
Wouldn't be this what you're looking for?
In that case, the request.getRequestDispatcher(newURI).forward(req, res) seems to do the trick, using only the filter.
#WebFilter(filterName = "AllRequestScanFilter", urlPatterns = "/*")
public class AllRequestScanFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
//EmployerViewTestBusinessWrapper wrapper = new EmployerViewTestBusinessWrapper(request);
String URI = request.getRequestURI();
if (URI.contains("abcd.jsp") && URI.contains("pages")) {
URI = URI.replaceFirst("/pages/","/pages/myapp/");
request.getRequestDispatcher(URI).forward(req, res);
} else {
chain.doFilter(req, resp);
}
}
public void init(FilterConfig config) throws ServletException {
}
}

What's mean the MonitorRequestWrapper and why am I not getting parameters from request?

I am working in Netbeans IDE and i have wrote JS-code for sending HTTP Request to server:
function applyFilter(){
idFilterJS = getRadioValue();
var url = "applyfilter?action=applyfilterXML&id=" + idFilterJS;
req = initRequest();
req.open("GET", url, true);
req.onreadystatechange = applyFilterCallBack;
req.send(null);
}
Next, I had a breakpoint in ApplyFilterServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
session = request.getSession();
String action = request.getParameter("action");
}
I have two questions:
What does MonitorRequestWraper mean for request variable during debug mode?
"request.getParameter("action");" returns null. Why?
Thanks!
It extends the request. Dig down into the attributes under "inherited" to find your attributes.
public class MonitorRequestWrapper extends HttpServletRequestWrapper

Java FilterImplementation for session checking

I creating a web application using JSF,Hibernate,Spring. I have added a filter for checking session. My Filter code is :
public class AdminFilter implements Filter{
private ArrayList<String> urlList;
#Override
public void init(FilterConfig filterConfig) throws ServletException {
String urls = filterConfig.getInitParameter("avoid-urls");
StringTokenizer token = new StringTokenizer(urls, ",");
urlList = new ArrayList<String>();
while (token.hasMoreTokens()) {
urlList.add(token.nextToken());
}
}
// Checking if user is logged in
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req= (HttpServletRequest) request;
HttpServletResponse resp= (HttpServletResponse) response;
String url = req.getServletPath();
HttpSession session = req.getSession();
if(!urlList.contains(url) && session.getAttribute("user")==null)
{
resp.sendRedirect(req.getContextPath() + "/backend/login/index.xhtml");
}
chain.doFilter(req, resp);
}
#Override
public void destroy() {
// throw new UnsupportedOperationException("Not supported yet.");
}
}
In the init method of filter i have some avoid URL for which session checking should be skipped, like for login page itself. This is working correct but this filter is restricting my CSS,images and JS to load on the login page.
Suggest me what is the problem in my filter ?
Your login page needs some resources (CSS, JS, Images) which are requested from browser in separate request which will be intercepted by Filter and since you don't have any parameters that skips such requests for resources (being used on login page) it will block this request
Suggestion:
You could use Spring-Security, rather than investing time in writing yours, it has got lots of flexibility by configuration
Based on your current config, Currently your filter is ignoring if the URL is for fetching css, images or any other resource.
boolean staticResources = (url.contains("css") || url.contains("images"));
if(!urlList.contains(url) && session.getAttribute("user")==null && !staticResources) {
resp.sendRedirect(req.getContextPath() + "/backend/login/index.xhtml");
}
This will avoid session checking for static contents.
Better way of doing this will be using the declarative security as part of Java EE Web Security using realm.

Categories

Resources