Upgrading to VaadinWebSecurity is breaking custom WebSocket - spring

I recently upgraded my project from Vaadin 23.1 to 23.2 and also upgraded my Spring Security configuration class to extend VaadinWebSecurity.
My project also has a custom WebSocket endpoint that is exposed at a certain URL.
Before the change to VaadinWebSecurity it was working fine. However after upgrading, it is not reachable any more.
Instead, it seems I am getting connected to a Vaadin WebSocket.
Probably the new SecurityFilterChain is overwriting my config.
Message received after connecting:
for(;;);[{"meta":{"async":true,"sessionExpired":true}}]
Security Config
#EnableWebSecurity
#Configuration
public class SecurityConfiguration extends VaadinWebSecurity {
public static final String LOGOUT_URL = "/";
public static final String WEBSOCKET_URl = "/websocket";
//...
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(WEBSOCKET_URl)
.permitAll();
super.configure(http);
setLoginView(http, LoginView.class, LOGOUT_URL);
}
}
Sample WebSocket Handler
#Configuration
#EnableWebSocket
public class Websocket implements WebSocketConfigurer {
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry
.addHandler(new WebSocketHandler() {
#Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
session.sendMessage(new TextMessage("this is a response"));
}
// ...
}, SecurityConfiguration.WEBSOCKET_URl)
.setAllowedOriginPatterns("*");
}
}
I created a minimal example project based on start.vaadin.com.
It contains a sample WebSocket Handler.
sample-webscoket-vaadin.zip
Vaadin / Flow version: 23.2.1
Java version: 17
Can someone give me some advice how to get the WebSocket running again?

Atmosphere handler is intercepting the request. I've did some tests and security config is fine since the connection is established. After excluding Atmosphere dependency Spring WS handler works as expected.
It seems to be a bug in the Flow, I've created https://github.com/vaadin/flow/issues/14602
Exclusion workaround:
<dependency>
<groupId>com.vaadin</groupId>
<!-- Replace artifactId with vaadin-core to use only free components -->
<artifactId>vaadin</artifactId>
<exclusions>
<exclusion>
<groupId>com.vaadin.external.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
</exclusion>
</exclusions>
</dependency>

Related

How single authentication can work for multiple server nodes in Spring Security

I am using weblogic for deploying my spring boot application, and my same application is deployed on multiple nodes.
For example the two node in which the application is deployed is 9001 and 9002.
With basic security even if I am authenticated on the Node 9001 and trying to access the same URL on second node i.e on 9002, I am again getting redirected again to spring login page for authentication.
I want that once I authenticate using username and password on any node. I need not to authenticate again, Even if I am requesting to any other node.
Any kind of clue or help will be appreciated.
Thanks in advance.
The Security configuration file is
package com.config;
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.config.http.SessionCreationPolicy;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("test")
.password("{noop}test")
.authorities("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/userdetail").authenticated()
.anyRequest().permitAll()
.and()
.formLogin();
}
}
In my case it worked for both node when I enabled RedisHttpSession.
Below is the code which worked for me.
#Configuration
#EnableRedisHttpSession
public class RedisConfig {
#Bean
public JedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory();
}
}
also in pom.xml I needed to make two dependencies(For Spring boot).
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
You can also take reference about EnableRedisHttpSession from spring docs, and about spring session from
https://docs.spring.io/spring-session/docs/current/api/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSession.html
https://www.baeldung.com/spring-session

Spring security doest not restrict access

I have Spring MVC project and try to add security. My problem is that spring doesn't deny access to pages. I mean if I go to /product page, it will open. I have the following security config:
#Configuration
#EnableWebSecurity
public class SecureConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("a").password("1")
.roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated();
http.csrf().disable();
}
}
At first, I thought, these methods are not executed by spring context, but then I found that they are executed.
if I understand correctly, this configuration should deny access to all pages, but the opposite happens, I can go to any page (/, /product, /test pages)
My security dependencies:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.4.0</version>
</dependency>
Application class:
public class Application implements WebApplicationInitializer {
Logger logger = LoggerFactory.getLogger(Application.class);
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(WebConf.class, SecureConfig.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(context));
dispatcher.addMapping("/*");
dispatcher.setLoadOnStartup(1);
}
}
I solved this problem by adding the following class:
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
SpringSecurityFilterChain did not work without this class, that's why security didn't work.

In Spring Boot Security Basic Authentication, why the default password is not getting overridden by custom ones

Even when I extend WebSecurityConfigurerAdapter class and override its methods: configure(HttpSecurity http) and configure(AuthenticationManagerBuilder auth) with custom users and roles and either add or remove #EnableWebSecurity annotation from this configuration concrete class, the default password is still getting generated and I cannot use http basic authentication with the custom credentials I declared inside configure() method.
I am always getting like below in the console:
Using generated security password: a2b4b374-65d2-4d20-a965-b34c00d44de9
turning off Spring Security by excluding SecurityAutoConfiguration.class is disabling the whole security which I don't want.
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
Security Configuration
#Configuration
#EnableWebSecurity
public class BookStoreSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("admin").password("{noop}password").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().and().antMatcher("/**").authorizeRequests().anyRequest().hasRole("USER").and().csrf().disable();
}
}
App Entry Point
#SpringBootApplication(scanBasePackages={"com.example.springbootsecurity.bookstore"})
public class BookStoreApp {
public static void main(String[] args) {
SpringApplication.run(BookStoreApp.class, args);
}
}
I expected that from postman I would be able to login through basic authentication of my custom credential: admin/password.
But I always get the default password at console and my declared user credentials don't ever work and always give 401 unauthorized http status
Please help me with the solution!

Spring security permitAll() does not work

<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
I have created a spring-boot application purely severed as resource server.
#Configuration
#EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll();
}
}
In my configuration class, I did the above (allow everything, just for experiment purpose). However, it still seems that all requests come to this server got 401 unauthorised error. PermitAll() does not seem to work.
Am I missing something here?
Thanks.

Vaadin 7 + Spring security configuration

I'm trying to configure Spring Security + Vaadin4Spring together with my Vaadin 7 application.
I have following code:
pom.xml security related dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>1.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.vaadin.spring</groupId>
<artifactId>spring-vaadin-security</artifactId>
<version>0.0.3-SNAPSHOT</version>
</dependency>
My MainUI class definition:
#VaadinUI
public class MainUI extends UI {
and Application class
#PropertySource(value = "classpath:application.properties")
#EnableAutoConfiguration
#ComponentScan
#EnableGlobalMethodSecurity
public class Application extends GlobalMethodSecurityConfiguration {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("admin").password("password").roles("ADMIN");
}
}
Right now when I'm trying to access http://localhost:8080/ I have following error message:
HTTP ERROR 404
Problem accessing /error. Reason:Request was not handled by any registered handler.Powered by Jetty://
What I'm doing wrong ? Please help me, I'm stuck on this the second day Without Spring security my application works perfectly, but without security it's doesn't have a big sense.. Thanks!
Solved at the vaadin4spring github: https://github.com/peholmst/vaadin4spring/issues/78

Resources