web-dev-qa-db-fra.com

La barre oblique codée (% 2F) avec le paramètre de chemin Spring RequestMapping donne HTTP 400

Ceci n'est pas un doublon une question référencée , car elle est spécifique à Spring. Celui qui a ajouté que (3 ans après le fait!) N'a pas pris la peine de lire le fil de la question ou du commentaire pour voir quelle était la vraie réponse. La réponse acceptée n'est pas tout à fait la réponse, mais l'auteur de la réponse n'est jamais revenu et l'a modifiée comme je l'ai demandé.

Étant donné la méthode de repos ci-dessous, Spring 3.1 génère une erreur 400 avec "La requête envoyée par le client était syntaxiquement incorrecte ()". lorsque le paramètre token contient une barre oblique encodée en URL (% 2F), par exemple, " https://somewhere.com/ws/stuff/lookup/resourceId/287559/token/R4o6lI%2FbBx43/userName/jim " Sans le% 2F tout fonctionne bien. Un tiers appelle déjà ce service (bien sûr!), Je ne peux donc pas modifier ce qu'il envoie, du moins à court terme. Des idées sur la façon de contourner ce problème côté serveur?

Ce problème est très bien décrit ici https://jira.springsource.org/browse/SPR-8662 bien que ce problème soit lié à UriTemplate que je n’utilise pas et que je peux dire.

@RequestMapping("/ws/stuff/**")
@Controller
public class StuffController {
  @RequestMapping(value = "/ws/stuff/lookup/resourceId/{resourceId}/token/{token}/userName/{userName}", method = RequestMethod.GET)
   public @ResponseBody
   String provisionResource(@PathVariable("resourceId") String resourceId, @PathVariable("token") String token, @PathVariable("userName") String userName, ModelMap modelMap,
         HttpServletRequest request, HttpServletResponse response) {
      return handle(resourceId, userName, request, token, modelMap);
   }
}

Remarque: Il s’agit de Glassfish 3.1.2, et au début c’était Grizzly/Glassfish qui n’acceptait pas la barre oblique mais 

-Dcom.Sun.grizzly.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true 

résolu cela. 

asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-2.http.encoded-slash-enabled=true 

n'a pas semblé aider.

28
Jim

Cela pourrait être votre réponse: urlencoded La barre oblique inverse rompt l'URL

Je suggère de ne pas mettre cela dans le chemin, déplacez-le vers un paramètre de demande.

Solution de contournement:

Vous pouvez changer le RequestMapping en 

@RequestMapping(value = "/ws/stuff/lookup/resourceId/**", method = RequestMethod.GET) 

puis analysez les variables de chemin manuellement à partir de l'objet de la demande.

9
Solubris

pour Spring-Boot, ce qui suit a fait le tour

@SpringBootApplication
public class Application extends WebMvcConfigurerAdapter {

    public static void main(String[] args) throws Exception {
        System.setProperty("org.Apache.Tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setUrlDecode(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }

}
13
iamiddy

Voici un correctif pour Spring 3.2.4 (devrait également fonctionner pour les autres versions). On doit écraser la valeur par défaut de UrlPathHelper

public class UrlPathHelperFixed extends UrlPathHelper {

    public UrlPathHelperFixed() {
        super.setUrlDecode(false);
    }

    @Override
    public void setUrlDecode(boolean urlDecode) {
        if (urlDecode) {
            throw new IllegalArgumentException("Handler [" + UrlPathHelperFixed.class.getName() + "] does not support URL decoding.");
        }
    }

    @Override
    public String getServletPath(HttpServletRequest request) {
        String servletPath = getOriginatingServletPath(request);
        return servletPath;
    }

    @Override
    public String getOriginatingServletPath(HttpServletRequest request) {
        String servletPath = request.getRequestURI().substring(request.getContextPath().length());
        return servletPath;
    }
}

Et l'injecter au gestionnaire de cartographie:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
    <property name="order" value="-1"></property>
    <property name="urlPathHelper">
        <bean class="com.yoochoose.frontend.spring.UrlPathHelperFixed"/>
    </property>
</bean>

Après une journée de travail acharné, cela fonctionne maintenant pour moi :-)

L’équipe de Spring a été suggérée sous la forme suivante: https://jira.springsource.org/browse/SPR-11101

6
30thh

Pour les applications de démarrage de printemps cela a fonctionné pour moi ..

Version 1 Ajouter 

org.Apache.Tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

dans votre fichier application.properties

Version 2 Exécutez votre application de démarrage à ressort comme ceci.

static void main(String[] args) {
    System.setProperty("org.Apache.Tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
    SpringApplication.run this, args
}

Version 3 ou exécutez votre application Java avec - Dorg.Apache.Tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH = true

Cette variable de chemin de barre oblique codée% 2F fixe pour moi.

5
manukyanv07

J'ai trouvé cette solution qui fonctionne pour moi;

System.setProperty("org.Apache.Tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");

juste avant springApplication.run (args);

et ajouter le code ci-dessous dans la classe d'application

 @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setUrlDecode(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
4
Ankur Gupta

Nous venons de rencontrer ce problème dans mon bureau, nous avons suivi la suggestion ci-dessus de ce que disait Solubris où vous l'avez mise dans un paramètre de requête. La seule exigence supplémentaire est que les données puissent également avoir un '&', ce qui gâcherait le paramètre query. Tout ce que nous avions à faire, c'était de coder le texte avant de l'envoyer dans l'URL et même de filtrer les "&".

0
rsteier