Spring Security + Vaadin Session No VaadinSession

时间:2017-09-19 14:56:09

标签: java ssl servlets spring-boot vaadin

我有一个基于某个github项目的vaadin会话的弹簧安全项目。一切正常,直到我创建一个新的配置静态类,我想指定需要SSL的路径。

这是我的项目和Application类处于其原始工作状态: https://github.com/czetus/dluznikApp/blob/master/src/main/java/com/danes/main/Application.java

将Application.java的代码添加到第一个静态类

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();
        }


    }

该项目正在编译和部署没有任何错误。当我启动localhost时问题开始:8080。我收到了一个定义的异常:

https://github.com/czetus/dluznikApp/blob/master/src/main/java/com/danes/main/servlet/VaadinSessionSecurityContextHolderStrategy.java

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]
...

如果删除注释@EnableWebSecurity,则没有错误,并且ssl无法正常工作。

当我调试时,我注意到在方法

中过早地调用了getSession
@Override
public void setContext(SecurityContext context) {
    getSession().setAttribute(SecurityContext.class, context);
}

在类VaadinSessionSecurityContextHolderStrategy.java

那么我该做什么或是否有其他方法不创建此配置类并使SSL保护此路径(模式)?

1 个答案:

答案 0 :(得分:1)

你可以跳过使用VaadinSessionSecurityContextHolderStrategy吗?使用线程本地策略的默认Spring安全设置应该可以工作。

修改

安全上下文通常存储在为请求提供服务的线程中。在Vaadin servlet获取请求之前运行安全筛选器,这意味着会话将不存在,因此安全筛选器无法使用Vaadin会话来存储安全上下文。

您可以使用会话初始化侦听器将相关用户数据添加到Vaadin会话当调用它时,过滤器已将用户信息添加到线程本地安全上下文持有者。

@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());
    }
}