Reputation: 11
I a have working spring security project with vaadin session based on some github project. All is working fine until I create a new configuration static class where I want to specify the path where SSL should be required.
Here is my project and Application class in its original working state: https://github.com/czetus/dluznikApp/blob/master/src/main/java/com/danes/main/Application.java
Added code to Application.java into first static class
public static class SecurityConfiguriation extends GlobalMethodSecurityConfiguration
@EnableWebSecurity
public static class WebSecurity extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requiresChannel()
.antMatchers("/v1*").requiresSecure();
}
}
The project is compiling and deploying wihtout any error. Problem starts when I start localhost:8080. I receive an exception defined here:
java.lang.IllegalStateException: No VaadinSession bound to current thread
at com.danes.main.servlet.VaadinSessionSecurityContextHolderStrategy.getSession(VaadinSessionSecurityContextHolderStrategy.java:41) ~[classes/:na]
at com.danes.main.servlet.VaadinSessionSecurityContextHolderStrategy.clearContext(VaadinSessionSecurityContextHolderStrategy.java:12) ~[classes/:na]
at org.springframework.security.core.context.SecurityContextHolder.clearContext(SecurityContextHolder.java:73) ~[spring-security-core-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:180) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
...
If I remove annotation @EnableWebSecurity there is no error and ssl is not working.
When I was debugging I noticed that getSession is invoked too early in method
@Override
public void setContext(SecurityContext context) {
getSession().setAttribute(SecurityContext.class, context);
}
in class VaadinSessionSecurityContextHolderStrategy.java
So what do I have to do or is there some other way to not create this configuration class and get this path (pattern) to be secured by SSL ?
Upvotes: 1
Views: 1533
Reputation: 1276
Could you skip using VaadinSessionSecurityContextHolderStrategy? The default Spring security setup with thread local strategy should work.
Edit
Security context is typically stored in the thread that serves the request. Security filter is run before Vaadin servlet gets the request and this means that the session will not exist yet so the security filter cannot use Vaadin session to store the security context.
You can add relevant user data to Vaadin session with session init listener When it gets called the filter has already added user information to the thread local security context holder.
@Component("vaadinServlet")
@WebServlet(urlPatterns = "/*", name = "MyVaadinServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = MyUi.class, productionMode = false)
public class MyVaadinServlet extends SpringVaadinServlet {
private static final Logger logger = LoggerFactory.getLogger(MyVaadinServlet.class);
@Override
protected void servletInitialized() throws ServletException {
getService().addSessionInitListener(this::onServletInit);
super.servletInitialized();
}
private void onServletInit(SessionInitEvent sessionInitEvent) {
SecurityContext securityContextOwnedByFilter = SecurityContextHolder.getContext();
VaadinSession session = sessionInitEvent.getSession();
User user = (User) securityContextOwnedByFilter.getAuthentication().getPrincipal();
session.setAttribute("user", user);
logger.info("User '{}' stored in session '{}'",
user.getUsername(),
session.getSession().getId());
}
}
Upvotes: 1