H2 database console spring boot Load denied by X-Frame-Options - h2

I`m building a skeletal project for dev with spring 4 boot security and others.
Using H2 while attempting to log into the db console and manage my db i get the following error. The page is blank, with 4 bugs in firebug konsole :
Load denied by X-Frame-Options: http://localhost:8080/console
With links to
/header.jsp?jsessionid=f71207a702c9177e57208414721bbe93 does not permit framing.
/query.jsp?jsessionid=f71207a702c9177e57208414721bbe93 does not permit framing.
/help.jsp?jsessionid=f71207a702c9177e57208414721bbe93 does not permit framing.
/tables.do?jsessionid=f71207a702c9177e57208414721bbe93 does not permit framing.
I can test the connection from console level - its ok.
DB works fine, import.sql works fine, i can create user entities withing spring is starting up.
The configuration i am using is from (and it works on spring 3.2 with xml configuration)
spring boot default H2 jdbc connection (and H2 console)
Using :
spring-boot-starter-parent
1.1.4.RELEASE

It's also possible to simplify the answer from #chrosciu with this:
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable();
}
}

Added the code below to Application.java and for now it works, default on port 8082, starts with spring app. It doesn`t hit the spot but for dev purposes it is all ok.
#Bean
org.h2.tools.Server h2Server() {
Server server = new Server();
try {
server.runTool("-tcp");
server.runTool("-tcpAllowOthers");
} catch (Exception e) {
e.printStackTrace();
}
return server;
}

This worked for me:
#EnableWebSecurity
#Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().addHeaderWriter(
new XFrameOptionsHeaderWriter(
new WhiteListedAllowFromStrategy(Arrays.asList("localhost"))));
}
}
Of course contents of white list should be adjusted in case when application is running on something different than localhost.

Related

An unwanted default login interface appears

I started a Springboot application looking to create a login/registration Webapp .
I only set up Thymeleaf and Bootstrap for the HTML template , and set up the service, the controller and the repository.
This is the first time this login interface shows and whenever I change the URL it goes back to localhost:8080/login
I made sure that the port is set on the current project, and that there is no request set for /login
It looks like there is a backend set up for it and I do not undrestand from where it is ...
This is from Springboot security auto configuration , I had to disable it manually adding a configurating class :
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity security) throws Exception
{
//security.httpBasic().disable(); // Did work only for GET
security.csrf().disable().authorizeRequests().anyRequest().permitAll(); // Works for GET, POST, PUT, DELETE
}
}

websocket spring boot setup

I have a spring boot application. I am trying to add the websocket piece to it. The problem is my angular client can't connect to it. I used smart websocket client google plugin, but still not able to connect. Here is the setup.
I am using Intellij Idea on localhost. the spring boot application is running on localhost:8080. I can see the WebSocketSession is runnign from intellij idea console.
Here is the setup:
#Slf4j
#RestController
public class WebsocketController {
#MessageMapping("/ws-on/hello")
#SendTo("/ws-on/greetings")
public UserStateIndicator greeting(UserStateIndicator indicator) throws Exception {
Thread.sleep(1000); // simulated delay
log.debug("websocket " + indicator.toString());
return indicator;
}
}
#Configuration
#EnableWebSocketMessageBroker
public class WebsocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/ws-on");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-on")
.setAllowedOrigins("http://localhost:4200")
.withSockJS();
}
}
my angular is running on localhost:4200.
I used ws://localhost:8080/ws-on as the url from StompJS to connect.
My question is how do I find the websocket url to connect, and how do I know the websocket is running on the spring boot server?
finally I figured it out. Because I am using SockJS on both angular and spring boot, so, the URL is actaully http not ws. the correct url to connect is then http://localost:8080/ws-on

AuthenticationSuccessEvent Listener for two spring applications connected through Shared Redis session

I am having two spring-boot application with shared session through Redis..
application-1 contains the login flow and application-2 uses the same session created on application-1,
Now i wanted to listen to the successful authentication on application-2.
Tried using InteractiveAuthenticationSuccessEvent listener as below ..
#EventListener({AuthenticationSuccessEvent.class, InteractiveAuthenticationSuccessEvent.class})
public void processAuthenticationSuccessEvent(AbstractAuthenticationEvent e) {
logger.info("Autenticación successful ....");
e.getAuthentication().getName();
}
Added the below code in securityConfig
#EnableWebSecurity
#Configuration
#Component
#Order
class SecurityConfig extends WebSecurityConfigurerAdapter {
.....
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationEventPublisher(authenticationEventPublisher());
}
#Bean
public DefaultAuthenticationEventPublisher authenticationEventPublisher() {
return new DefaultAuthenticationEventPublisher();
}
}
But 'InteractiveAuthenticationSuccessEvent' in application-2 is not triggered on authenticating on application-1..
Can someone guide me on this ?
I have used Redis PubSub to resolve my problem by listening to the Authentication Event from Application-1 to Application-2..

Spring Boot - custom 404 page with standalone tomcat

I am running a Spring boot application inside a standalone tomcat instance, and I am trying to override the error pages. From my understanding, Spring provides a filter ErrorPageFilter that allows me to just setup error pages as normal for Springs EmbeddedServletContainerCustomizer to handle this case exactly.
So I have my standard auto configuration/servlet initializer in one class:
#Configuration
#ComponentScan
#EnableAutoConfiguration(exclude = [ GroovyTemplateAutoConfiguration, SecurityAutoConfiguration, ErrorMvcAutoConfiguration, JmxAutoConfiguration ] )
class Application extends SpringBootServletInitializer {
#Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
application.sources( Application )
}
(I am using the same class for autoconfiguration and servlet init, which is why i just pass my Application class in the configure method)
Looking at the source code for SpringBootServletInitializer it looks like the ErrorPageFilter class is being added by just extending that class here. I have turned off the ErrorMvcAutoConfiguration - but again, looking at that source code it looks like that is just setting default error pages and not actually setting anything up with the ErrorPageFilter.
I then have my error config file:
#Configuration
class ErrorConfiguration implements EmbeddedServletContainerCustomizer {
#Override public void customize( ConfigurableEmbeddedServletContainer container ) {
container.addErrorPages(new ErrorPage( HttpStatus.NOT_FOUND, "/errors/404" ))
}
However, if I just visit an invalid URL, and I DispatcherServlet can't find a match then I just get tomcats /404.html - not my view linked to "/errors/404" (I have this path mapped to a thymeleaf view template, that works fine - if I navigate to /errors/404 it displays ok)
Any ideas why my custom error page is not working? tracing the logs, I get a line about the ErrorPageFilter being configured and setup ok on application startup, but then no mentions of the filter doing anything when a request comes in.
You can use following code for older versions of spring boot (0.5.x)
public class ServerCustomization extends ServerProperties {
#Override
public void customize(ConfigurableEmbeddedServletContainerFactory factory) {
super.customize(factory);
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
"/yourpath/error-not-found.jsp"));
factory.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,
"/yourpath/error-internal.jsp"));
factory.addErrorPages(new ErrorPage("/yourpath/error-other.jsp"));
}
}
Newer spring boot versions (1.X.RELEASE) has some refactoring around ServerProperties. See below,
public class ServerCustomization extends ServerProperties {
#Override
public void customize(ConfigurableEmbeddedServletContainer container) {
super.customize(container);
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
"/jsp/404.jsp"));
container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,
"/jsp/500.jsp"));
container.addErrorPages(new ErrorPage("/jsp/error.jsp"));
}
}
Then define a bean to inject ServerProperies.
#Bean
public ServerProperties getServerProperties() {
return new ServerCustomization();
}
Sample project posted in git
Very Important: If you are using maven to build, You must store all the resource files under src/main/resources folder. Otherwise maven will not add those files to final jar artifact.
You can either use Spring Boot's builtin error view by implementing a view named error, or switch it off by setting error.whitelabel.enabled=false property and implement your own. It's explained more in the docs.

How to redirect automatically to https with Spring Boot

How I can easily configure the embedded tomcat server to redirect all http traffic to https? I have Spring Boot running on an ec2 instance that is behind an elastic load balancer. I have configured the ELB to handle ssl for me (which is awesome) and it sets the X-FORWARDED-PROTO header to "https". I want to detect when that isn't set, and redirect the user to force them to use https if they aren't already.
So far, I have tried adding the following to my application.properties file with no luck:
server.tomcat.protocol-header=x-forwarded-proto
security.require-ssl=true
My answer is a little late but I just recently had this problem and want to post a solution which worked for me.
Originally, I thought that setting tomcat up to use the X-Forwarded headers would suffice but the RemoteIPValve from Tomcat, which should normally handle this case, didnt work for me.
My solution was to add an EmbeddedServletContainerCustomizer and add a ConnectorCustomizer:
(note that I am using Tomcat 8 here)
#Component
public class TomcatContainerCustomizer implements EmbeddedServletContainerCustomizer {
private static final Logger LOGGER = LoggerFactory.getLogger(TomcatContainerCustomizer.class);
#Override
public void customize(final ConfigurableEmbeddedServletContainer container) {
if (container instanceof TomcatEmbeddedServletContainerFactory) {
final TomcatEmbeddedServletContainerFactory tomcat = (TomcatEmbeddedServletContainerFactory) container;
tomcat.addConnectorCustomizers(connector -> {
connector.setScheme("https");
connector.setProxyPort(443);
});
LOGGER.info("Enabled secure scheme (https).");
} else {
LOGGER.warn("Could not change protocol scheme because Tomcat is not used as servlet container.");
}
}
}
The important thing is that you not only set the Scheme to https but also the ProxyPort without which all internal redirects from Spring Boot were routed to port 80.
The configuration property security.require-ssl doesn't work when basic authentication is disabled (at least on old versions of Spring Boot). So you probably need to secure all the requests manually with code similar to this one:
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Inject private SecurityProperties securityProperties;
#Override
protected void configure(HttpSecurity http) throws Exception {
if (securityProperties.isRequireSsl()) http.requiresChannel().anyRequest().requiresSecure();
}
}
You can check my full answer here: Spring Boot redirect HTTP to HTTPS
You will need a keystore file and few config classes.
The below link explains it in detail.
Https on embedded tomcat
Spring Boot 2.0 redirection of http to https:
Add the following to the #Configuration
#Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
#Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(redirectConnector());
return tomcat;
}
private Connector redirectConnector() {
Connector connector = new Connector(
TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}

Resources