Vaadin 23 не может полностью перезагрузить приложение после повторного развертывания

Прямо сейчас я готовлю свое приложение Vaadin 23.2.5 к производству, и очень часто после повторного развертывания приложение не может полностью перезагрузиться и зависает с толстой синей полосой выполнения вверху.

Единственная проблема, которую я вижу, это следующая проблема JS в консоли браузера:

Fire Fox

Хром

Кроме того, исходя из моих предыдущих вопросов на эту тему — я полностью удалил компонент Grid из приложения, но, как вы видите, проблема все еще существует. Как решить эту проблему?

ОБНОВЛЕНО

Мои конфиги:

      @Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfiguration extends VaadinWebSecurityConfigurerAdapter {

    private final ClientRegistrationRepository clientRegistrationRepository;
    private final GrantedAuthoritiesMapper authoritiesMapper;
    private final ProfileService profileService;

    SecurityConfiguration(ClientRegistrationRepository clientRegistrationRepository,
                          GrantedAuthoritiesMapper authoritiesMapper, ProfileService profileService) {
        this.clientRegistrationRepository = clientRegistrationRepository;
        this.authoritiesMapper = authoritiesMapper;
        this.profileService = profileService;
        SecurityContextHolder.setStrategyName(VaadinAwareSecurityContextHolderStrategy.class.getName());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http
                // Enable OAuth2 login
                .oauth2Login(oauth2Login ->
                        oauth2Login
                                .clientRegistrationRepository(clientRegistrationRepository)
                                .userInfoEndpoint(userInfoEndpoint ->
                                        userInfoEndpoint
                                                // Use a custom authorities mapper to get the roles from the identity provider into the Authentication token
                                                .userAuthoritiesMapper(authoritiesMapper)
                                )
                                // Use a Vaadin aware authentication success handler
                                .successHandler(new KeycloakVaadinAuthenticationSuccessHandler(profileService))
                )
                // Configure logout
                .logout(logout ->
                        logout
                                // Enable OIDC logout (requires that we use the 'openid' scope when authenticating)
                                .logoutSuccessHandler(logoutSuccessHandler())
                                // When CSRF is enabled, the logout URL normally requires a POST request with the CSRF
                                // token attached. This makes it difficult to perform a logout from within a Vaadin
                                // application (since Vaadin uses its own CSRF tokens). By changing the logout endpoint
                                // to accept GET requests, we can redirect to the logout URL from within Vaadin.
                                .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"))
                );
    }

    @Bean
    @Primary
    public SpringViewAccessChecker springViewAccessChecker(AccessAnnotationChecker accessAnnotationChecker) {
        return new KeycloakSpringViewAccessChecker(accessAnnotationChecker, "/oauth2/authorization/keycloak");
    }

    private OidcClientInitiatedLogoutSuccessHandler logoutSuccessHandler() {
        var logoutSuccessHandler = new OidcClientInitiatedLogoutSuccessHandler(clientRegistrationRepository);
        logoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}");
        return logoutSuccessHandler;
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
        // Don't apply security rules on our static pages
        web.ignoring().antMatchers("/session-expired", "/images/*");
    }

    @Bean
    public PolicyFactory htmlSanitizer() {
        // This is the policy we will be using to sanitize HTML input
        return Sanitizers.FORMATTING.and(Sanitizers.BLOCKS).and(Sanitizers.STYLES).and(Sanitizers.LINKS);
    }

}


@Component
class VaadinSessionConfiguration implements VaadinServiceInitListener, SystemMessagesProvider, SessionDestroyListener {

    private final String relativeSessionExpiredUrl;

    VaadinSessionConfiguration(ServerProperties serverProperties) {
        relativeSessionExpiredUrl = UriComponentsBuilder.fromPath(serverProperties.getServlet().getContextPath()).path("logout").build().toUriString();
    }

    @Override
    public SystemMessages getSystemMessages(SystemMessagesInfo systemMessagesInfo) {
        var messages = new CustomizedSystemMessages();
        // Redirect to a specific screen when the session expires. In this particular case we don't want to logout
        // just yet. If you would like the user to be completely logged out when the session expires, this URL
        // should the logout URL.
        messages.setSessionExpiredURL(relativeSessionExpiredUrl);
        return messages;
    }

    @Override
    public void sessionDestroy(SessionDestroyEvent event) {
        // We also want to destroy the underlying HTTP session since it is the one that contains the authentication
        // token.
        try {
            event.getSession().getSession().invalidate();
        } catch (Exception ignore) {
            // Session was probably already invalidated.
        }
    }

    @Override
    public void serviceInit(ServiceInitEvent event) {
        event.getSource().setSystemMessagesProvider(this);
        event.getSource().addSessionDestroyListener(this);
    }

}

public final class VaadinAwareSecurityContextHolderStrategy implements SecurityContextHolderStrategy {

    private final ThreadLocal<SecurityContext> contextHolder = new ThreadLocal<>();

    @Override
    public void clearContext() {
        contextHolder.remove();
    }

    @Override
    @NonNull
    public SecurityContext getContext() {
        var context = contextHolder.get();
        if (context == null) {
            context = getFromVaadinSession().orElseGet(() -> {
                var newCtx = createEmptyContext();
                // This copies the behaviour of ThreadLocalSecurityContextHolder.
                contextHolder.set(newCtx);
                return newCtx;
            });
        }
        return context;
    }

    @NonNull
    private Optional<SecurityContext> getFromVaadinSession() {
        // Don't store this security context in the ThreadLocal as that may lead to the context leaking
        // into other sessions as threads may be reused.
        var session = VaadinSession.getCurrent();
        if (session == null) {
            return Optional.empty();
        }
        var securityContext = session.getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
        if (securityContext instanceof SecurityContext) {
            return Optional.of((SecurityContext) securityContext);
        } else {
            return Optional.empty();
        }
    }

    @Override
    public void setContext(@NonNull SecurityContext securityContext) {
        contextHolder.set(requireNonNull(securityContext));
    }

    @Override
    @NonNull
    public SecurityContext createEmptyContext() {
        return new SecurityContextImpl();
    }
}

ОБНОВЛЕНО 1

0 ответов

Другие вопросы по тегам