Share cookies in Spring MVC - spring-mvc

I have an existing web application which runs on
https://subdomain.example.com
Now I like to have additional subdomains
https://subdomain2.example.com
How can I set the following using Spring MVC so that the user will not be prompted for authentication again after being redirected from the first domain to the second domain ?
Set-Cookie: name=value; domain=example.com

Look at this controller example, but keep in mind 2 things:
putting an arbitrary fixed domain will not allow you to access the cookie when you work in your local environment if you connect to 127.0.0.1.
your cookie could be read by all the subdomain present on that host(example.com), not only by the ones you want.
Class:
package com.test.foo;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
#RequestMapping("/foo")
public class FooController {
#RequestMapping("/cookie")
public String setCookie(HttpServletRequest request, HttpServletResponse response) {
String value = "value";
Cookie cookie = new Cookie("name", value);
cookie.setPath("/");//<-- important
cookie.setDomain("example.com");
response.addCookie(cookie);
return "foo/index";//your view
}
}

Related

How to fix remote ejb lookup in Websphere Liberty?

I am trying to access the ejb deployed on websphere liberty 18.0.0.3
The binding location is: java:global/ITSORemote/ITSORemoteEJB/HelloRemoteEJB!com.ibm.itso.ejbRemote.view.HelloRemoteEJBRemote
My ORB configuration in the server.xml is:
<orb nameService="corbaname::<ipaddress>:2809" iiopEndpointRef="defaultIiopEndpoint">
<iiopEndpoint host= id="defaultIiopEndpoint" iiopPort="2809">
</iiopEndpoint>
</orb>
I have also added ejbRemote-3.2 in feature manager
I have two scenarios:
1. Access ejb from a client code running on the same server - This works using the url java:global/ITSORemote/ITSORemoteEJB/HelloRemoteEJB!com.ibm.itso.ejbRemote.view.HelloRemoteEJBRemote
2. Access ejb from a client code running on the different server - This does not work using the url
corbaname::(ipaddress):2809#ejb/global/ITSORemote/ITSORemoteEJB/HelloRemoteEJB!com.ibm.itso.ejbRemote.view.HelloRemoteEJBRemote
I am using the following code for lookup:
package com.ibm.remoteaccess;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Hashtable;
import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ibm.itso.ejbRemote.view.HelloRemoteEJBRemote;
/**
* Servlet implementation class RemoteAccess
*/
#WebServlet("/RemoteAccess")
public class RemoteAccess extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
try {
out.println("Hi");
Context ctx = new InitialContext();
Object ejbBusIntf = ctx.lookup("java:global/ITSORemote/ITSORemoteEJB/HelloRemoteEJB!com.ibm.itso.ejbRemote.view.HelloRemoteEJBRemote");
HelloRemoteEJBRemote bean = (HelloRemoteEJBRemote)PortableRemoteObject.narrow(ejbBusIntf, HelloRemoteEJBRemote.class);
out.println(bean.hello());
}
catch (NamingException e) { // Error getting the business interface
out.println(e);
}
}
}
There is no error thrown in the console also. What could be the problem?
There is a functional acceptance test (FAT) in open-liberty that looks up a remote EJB from one liberty server to an EJB on a second liberty server. The specific test can be found here:
https://github.com/OpenLiberty/open-liberty/blob/master/dev/com.ibm.ws.ejbcontainer.remote_fat/test-applications/RemoteClientWeb.war/src/com/ibm/ws/ejbcontainer/remote/client/web/RemoteTxAttrServlet.java
Each server process includes the ejbRemote-3.2 feature and an iiopEndpoint configuration (different ports since the test runs both serves on the same host).
https://github.com/OpenLiberty/open-liberty/blob/master/dev/com.ibm.ws.ejbcontainer.remote_fat/publish/servers/com.ibm.ws.ejbcontainer.remote.fat.RemoteServerClient/server.xml
If you are not seeing any errors, then perhaps the iiopEndpoint is not configured properly in the client side server (as the ORB will not start without it). For example, the default iiop port is 2809, and if both servers are on the same host, then they cannot both use that port. Setting both servers to the same port would result in the ORB not starting properly on one of the servers, and lookups would fail.
A lookup across servers would use corbaname, and the value you have specified appears to be correct.

Spring boot application not able to access rest path

I am trying to set up the rules for spring boot to allow/deny access for specific paths. I looked up various examples and stack overflow question, but none was helpful. I created the configuration file as follows:
package xyz.blackmonster.window.configs;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
#EnableWebSecurity
#Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Value("${admin.console.username:admin}")
private String username;
#Value("${admin.console.password:admin}")
private String password;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser(username)
.password(passwordEncoder().encode(password)).roles("ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/assets/**", "/api/order/calculate", "/api/order/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.and()
.formLogin()
.loginPage("/login.html")
.defaultSuccessUrl("/admin/orders.html")
.failureUrl("/login.html?error=true")
.and()
.logout().logoutSuccessUrl("/");
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
I can access the "/" without a problem. The page is loaded and show with the help of the MVC controller. But the paths that I defined as REST end points, I am not able to access them. I keep getting a 403 response:
{"timestamp":"2018-10-08T19:22:04.963+0000","status":403,"error":"Forbidden","message":"Forbidden","path":"/api/order/calculate"}
What is wrong with my configuration? As you can see from the class, I even went one further and specifically set the calculate end point as oppose to having the ** to include all subpaths.
If "/" is working and "/api/order/calculate" is not, it means that they have different HTTP verbs.
"/" - is a GET request
"/api/order/calculate" - is a POST request
By default, spring security will enable csrf protection (only for POST because GET is considered safe). If you are getting 403, it means that you are not sending csrf header => your access is forbidden.
You said that this is a REST endpoint, so you should disable csrf for this endpoints. To do that, please update your configuration with:
1.disable csrf in general (not recommended if you have web forms)
http.csrf()
.disable();
2.if you need to ignore csrf only for specific endpoints, you can add:
http.csrf()
.ignoringAntMatchers("/api/order/calculate")

How can I enable spring boot 1.2.5, using jersey, to print the raw http request and response to the console?

I have a spring boot 1.2.5 service that uses jersey 2. I see the requests in my own logs but I'd like to see the raw http request and response in the console as well. How can you turn on printing http traffic to the console?
import java.util.logging.Logger;
import org.glassfish.jersey.filter.LoggingFilter;
import javax.ws.rs.ApplicationPath;
import org.springframework.stereotype.Component;
#Component
#ApplicationPath("/")
public class JerseyConfiguration extends ResourceConfig {
private static final Logger log = Logger.getLogger(JerseyConfiguration.class.getName());
public JerseyConfiguration() {
...
register(new LoggingFilter(log, true));
}
}

How to use spring security to prevent xss and xframe attack

I look spring web site and want to prevent my website form xss and xframe attack
But My english is not well enough to figure out what to set
Please guide me what else should I setting??
I just add a WebSecurityConfig.java under src/com/test/web/security
Here is my code :
package com.test.web.security;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#EnableWebSecurity
#Configuration
#ComponentScan
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.headers();
}
}
If you just specify the same code that you have above, Spring Security should automatically add all of the relevant security headers. Per the docs:
If you are using Spring Security’s Java configuration, all of the
default security headers are added by default.
Also:
As soon as you specify any headers that should be included, then only
those headers will be include
See details and code samples in this section:
http://docs.spring.io/spring-security/site/docs/3.2.0.RELEASE/reference/htmlsingle/#default-security-headers

Spring 3.1 MVC: GET & POST on the same mapping, can it work?

I'm learning Spring 3.1.
My webapp name is "acme".
The url is roughly https://blah.blah.blah/acme
That URL is set up to display the login.jsp
I have a "/login" mapping in my controller that my login.jsp submits to
If something goes wrong it return the user to the login.jsp with this url in the browser:
https://blah.blah.blah/acme/login
The "/login" mapping is set up to handle POST requests, so I am concerned about users bookmarking
https://blah.blah.blah/acme/login, and getting the error message of "GET request not supported"
So, I thought I would put in a function to handle GET requests to /login to reroute through my general mapping handler for "/" and "/home":
Login.Controller.java
package gov.noaa.acme.controller;
import java.security.Principal;
import javax.servlet.http.*;
import org.springframework.stereotype.Controller;
import org.springframework.validation.*;
import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.apache.log4j.Logger;
#Controller
public class LoginController {
private static final Logger logger = Logger.getLogger(LoginController.class);
#RequestMapping({"/","home"})
public String home(ModelMap model,HttpSession session,HttpServletRequest request) {
// Do some stuff
return "login";
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String login_get(){
logger.debug("started...");
return "forward:home";
}
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(#ModelAttribute("laph") LAPH laph,
BindingResult bindingResult,
ModelMap model,
HttpSession session,
HttpServletRequest request,
HttpServletResponse response,
#RequestParam(required=true) String last_usertype) {
if (bindingResult.hasErrors()) {
logger.debug("Error returning home");
return "home";
}
logger.debug("Started ....");
// Do authentication
if (!isAuthenticated) {
model.put("status_message", error_message);
return "login";
}
// success, send newly authenticated user to a search page
nextView = "search";
return "redirect:" + nextView;
}
}// end class LoginController
My logs show that I am not even reaching the controller method for handling GET requests for /login, I'm still getting the error messages that GET is not supported for /login.
Any ideas on how I can fix this?
Thanks
Steve
I am concerned about users bookmarking https:// blah.blah.blah/acme/login, and getting the error message of "GET request not supported".
Your method signatures are correct; with the annotations you have placed on login_get and login, Spring will not be confused and will invoke the correct methods for GET and POST requests.
Your method home is wrong; it returns the string "login", but I guess you do not have a view named login and that you would like it to invoke one of the login methods. In that case you should have returned "forward:login", but this solution is not much better.
My advice is:
/home should render the home view, by using file home.jsp or whatever view technology you're using.
Use a HandlerInterceptor to check whether a user is logged in, and if not, only then you redirect him to the login url.

Resources