2017-07-24 3 views
3

J'ai un problème lors de l'utilisation de la sécurité de printemps dans un projet vaadin avec spring-boot. Donc j'utilise un Addon PdfViewer pour afficher les fichiers PDF. Mais je reçois le message d'erreur suivant:404 pour les fichiers js lors de l'utilisation de spring boot avec vaadin

error:"Not Found" 
message:"No message available" 
path:"/APP/PUBLISHED/pdf.worker.js" 
status:404 

et ma configuration de sécurité du printemps ressemble à ceci:

@Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
       .headers() 
       .defaultsDisabled() 
       .frameOptions().sameOrigin().and() 
       .csrf().disable() // Use Vaadin's CSRF protection 
       .authorizeRequests().antMatchers("/").permitAll() 
       .antMatchers("/vaadinServlet/HEARTBEAT/**").permitAll() 
       .antMatchers("/vaadinServlet/UIDL/**").permitAll() 
       .antMatchers("/vaadinServlet/APP/PUBLISHED/**").permitAll() 
       .antMatchers("login?debug").permitAll() 
       .antMatchers("/#!pwdreset/*").permitAll() 
       .antMatchers("/pwdreset/*").permitAll() 
       .and() 
       .authorizeRequests() 
       .and() 
       .formLogin().loginPage("/#!login").permitAll() 
       .and() 
       .logout().logoutUrl("/#!login?logout").logoutSuccessUrl("/").permitAll().and() 
       .sessionManagement().sessionFixation().newSession(); 

    } 

@Override 
    public void configure(WebSecurity web) throws Exception { 
     web.ignoring().antMatchers("/resources/**", "/VAADIN/**"); 
    } 

vérification Ainsi, les fichiers chargés dans Chrome je vois un dossier /vaadinServlet/APP/PUBLIÉ/ et il y a tous les fichiers nécessaires.

L'utilisation de l'addon sans ressort de sécurité fonctionne bien, donc n'importe qui une idée?


Mise à jour

Il ne semble pas être lié à la sécurité au printemps, parce que je reçois un comportement similaire tout en testant la Addon dans un nouveau projet simple. Il semble être un problème avec le démarrage de printemps.

Pour reproduire ce problème dont vous avez besoin (full project for download):

    botte ressort de base
  • + Vaadin squelette app
  • PDF simple et sous /webapp/files
  • PdfViewer add-on dans votre pom et widgetset compilé
  • le ci-dessous interface utilisateur simple
@Theme("mytheme") 
@SpringUI 
@Widgetset("org.test.AppWidgetSet") 
public class MyUI extends UI { 
    @Override 
    protected void init(VaadinRequest vaadinRequest) { 
     final VerticalLayout layout = new VerticalLayout(); 
     String basepath = VaadinService.getCurrent().getBaseDirectory().getAbsolutePath(); 
     File file = new File(basepath.concat("/files/test.pdf")); 
     if (file.exists()) { 
      PdfViewer pdfViewer = new PdfViewer(file); 
      Label info = new Label("File was found!"); 
      layout.addComponents(info, pdfViewer); 
     } else { 
      Label info = new Label("no file found!"); 
      layout.addComponent(info); 
     } 
     setContent(layout); 
    } 
} 
  • outils open développeur chrome & avec l'onglet Network sélectionné, accéder à l'application et vous devriez voir une demande de pdf.worker.js échouent.
+0

Seriez-vous en mesure de fournir un [sscce] (http://sscce.org) pour reproduire votre problème? Rien d'extraordinaire, juste un pom minimum, une interface utilisateur, une configuration spring-boot et un lanceur (classe principale) qui produit cette erreur. Je ne vois rien de mal avec votre config, peut-être que vous pourriez déplacer tous les chemins des ressources statiques vers la liste de matcher 'ignore' dans la méthode' configure', mais cela ne devrait pas poser de problème de toute façon.J'ai une configuration similaire mais la mienne fonctionne bien, donc sans la reproduire il serait difficile à comprendre (pour moi au moins) – Morfic

+0

@Morfic Je viens de mettre à jour ma question car il semble y avoir un problème avec le démarrage au printemps et il n'a rien à voir avec la sécurité du printemps. En créant un exemple, j'obtiens la même erreur que dans mon projet. Peut-être avez-vous une idée sur la façon de résoudre ce problème. –

Répondre

1

TL; DR; Version:

Une deuxième demande est déclenchée par pdf.js télécharger pdf.worker.js, mais il ne correspond pas au chemin /vaadinServlet/APP/PUBLISHED/pdf.worker.js géré par l'auto-configuration VaadinServlet, il est juste /APP/PUBLISHED/pdf.worker.js.

La solution la plus simple que je pourrais trouver, est un contrôleur qui forwards la demande au VaadinServlet:

import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 

@Controller 
public class PdfJsRedirectController { 
    private static final String WORKER_JS_INCORRECT_PATH = "/APP/PUBLISHED/pdf.worker.js"; 
    private static final String WORKER_JS_CORRECT_FORWARD_PATH = "forward:/vaadinServlet/APP/PUBLISHED/pdf.worker.js"; 

    @RequestMapping(value = WORKER_JS_INCORRECT_PATH) 
    public String forwardWorkerJsRequestToVaadin() { 
     return WORKER_JS_CORRECT_FORWARD_PATH; 
    } 
} 

détaillée Version:

Alors, j'ai passé quelques-uns temps de débogage cela, et il se trouve être une combinaison de configs malheureux:

  • ressort servlet répartiteur écoute
  • servlet ressort Vaadin écoute
  • un Bugfix pdf.js/woraround

Ce qui se passe est, le printemps enregistre une DispatcherServlet demandes au service de /*. et Vaadin enregistre un VaadinSpringServlet pour les /vaadinServlet/* & /VAADIN chemins:

ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 
ServletRegistrationBean : Mapping servlet: 'springVaadinServlet' to [/vaadinServlet/*, /VAADIN/*] 

coexister avec le servlet répartiteur et être en mesure de répondre à des demandes aussi sur «/* », Vaadin enregistre également un contrôleur de transfert pour la UI chemins. Par exemple, les demandes sur /MyUI seront transmises au /vaadinServlet/MyUI (voir le VaadinServletConfiguration sources pour plus de détails).

Jusqu'à maintenant tout fonctionne bien et vous ne devriez avoir aucun problème. Tout comme vous l'avez dit, en regardant le dev-tools chrome tous les fichiers js sont là, alors quel est le problème? Si vous regardez closley aux demandes faites lorsque vous accédez à votre application, vous remarquerez que en fait il y a 2 demandes de pdf.worker.js - le premier qui réussit, et celui qui vous donne la 404:

pdf.worker.js requests

La colonne Initiator pour l'appel qui échoue, est en réalité pdf.js:2344 et si vous définissez un point d'arrêt, vous pouvez réellement voir que workerSrc=/APP/PUBLISHED/pdf.worker.js, valeur qui est définie dans pl.pdfviewer.client.ui.PdfViewer.java. Vous pouvez faire défiler horizontalement un peu pour pouvoir voir le code, donc je l'ai formaté ci-dessous:

public native void loadResourcePdf(String fileName, VPdfViewer instance)/*-{ 
    var pdfviewer = [email protected]::jsObject; 
    pdfviewer.work = false; 
    if ((pdfviewer.fileName == null || pdfviewer.fileName != fileName) && fileName != null) { 
     $wnd.PDFJS.disableStream = true; 
======> $wnd.PDFJS.workerSrc = 'APP/PUBLISHED/pdf.worker.js'; 
     $wnd.PDFJS.getDocument(fileName).then(function (pdf) { 
      pdfviewer.pdfFile = pdf; 
      pdfviewer.fileName = fileName; 
      pdfviewer.pageCount = pdf.numPages; 
      if (pdfviewer.pageNumber == 0 && pdf.numPages > 0) { 
       pdfviewer.pageNumber = 1; 
      } 
      pdfviewer.showPdfPage(pdfviewer.pageNumber); 
     }); 
    } 

}-*/; 

js debug

Dans un environnement régulier Vaadin, /APP/PUBLISHED/pdf.worker.js travaillerait hors de la boîte, mais nous sommes maintenant dans un légèrement modifié donc nous avons besoin de quelques ajustements. En bout de ligne, nous pouvons utiliser une approche similaire à ce que Vaadin auto-configuration fait, et rediriger la demande /APP/PUBLISHED/pdf.worker.js à /vaadinServlet/APP/PUBLISHED/pdf.worker.js et enfin surmonter le problème. Pour des raisons de concision, le contrôleur de redirection peut être vu au début de ce post.

working pdf

+0

Merci, ça marche! Je n'ai pas regardé les sources. Je vais créer un problème pour le créateur addon. –

+0

@RedGato pas de problème. Je n'ai pas eu le temps d'enquêter plus avant, mais je ne suis pas sûr qu'il puisse faire quelque chose. S'il était possible de déterminer dynamiquement le chemin, nous pourrions avoir un correctif, sinon nous devrons toujours compter sur cette solution de contournement. Néanmoins, si vous ouvrez le problème, assurez-vous d'ajouter un lien vers cette question pour référence. À votre santé – Morfic