spring的websocket访问时403

spring的websocket访问时403

注:仅支持关闭sockjs的情况,如果需要开启sockjs,那么以下内容就不用看了
先说解决方案,在配置websocket的xml语句块中:

<websocket:handlers allowed-origins="*">
websocket:handlers>

添加allowed-origins属性,具体值看自己的需要,如有多个用 “,”隔开。

原因:下面是spring在初始化websocket的相关代码

class HandlersBeanDefinitionParser implements BeanDefinitionParser {

    private static final String SOCK_JS_SCHEDULER_NAME = "SockJsScheduler";

    private static final int DEFAULT_MAPPING_ORDER = 1;


    @Override
    public BeanDefinition parse(Element element, ParserContext context) {
        Object source = context.extractSource(element);
        CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
        context.pushContainingComponent(compDefinition);

        String orderAttribute = element.getAttribute("order");
        int order = orderAttribute.isEmpty() ? DEFAULT_MAPPING_ORDER : Integer.valueOf(orderAttribute);

        RootBeanDefinition handlerMappingDef = new RootBeanDefinition(WebSocketHandlerMapping.class);
        handlerMappingDef.setSource(source);
        handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        handlerMappingDef.getPropertyValues().add("order", order);
        String handlerMappingName = context.getReaderContext().registerWithGeneratedName(handlerMappingDef);

        RuntimeBeanReference sockJsService = WebSocketNamespaceUtils.registerSockJsService(
                element, SOCK_JS_SCHEDULER_NAME, context, source);

        HandlerMappingStrategy strategy;
        // 以下为主要代码
        if (sockJsService != null) {
            strategy = new SockJsHandlerMappingStrategy(sockJsService);
        }
        else {
            RuntimeBeanReference handshakeHandler = WebSocketNamespaceUtils.registerHandshakeHandler(element, context, source);
            Element interceptorsElement = DomUtils.getChildElementByTagName(element, "handshake-interceptors");
            ManagedListsuper Object> interceptors = WebSocketNamespaceUtils.parseBeanSubElements(interceptorsElement, context);
            String allowedOriginsAttribute = element.getAttribute("allowed-origins");
            List allowedOrigins = Arrays.asList(StringUtils.tokenizeToStringArray(allowedOriginsAttribute, ","));
            interceptors.add(new OriginHandshakeInterceptor(allowedOrigins));
            strategy = new WebSocketHandlerMappingStrategy(handshakeHandler, interceptors);
        }

        ManagedMap urlMap = new ManagedMap();
        urlMap.setSource(source);
        for (Element mappingElement : DomUtils.getChildElementsByTagName(element, "mapping")) {
            strategy.addMapping(mappingElement, urlMap, context);
        }
        handlerMappingDef.getPropertyValues().add("urlMap", urlMap);

        context.registerComponent(new BeanComponentDefinition(handlerMappingDef, handlerMappingName));
        context.popAndRegisterContainingComponent();
        return null;
    }
    // 其他代码已省略

}

应该可以看到,如果开启sockjs则不会执行else代码块中代码,那么为了执行else代码块就必须关闭sockjs。所以该方式仅支持关闭sockjs。
在 websocket:handlers 标签添加 allowed-origins属性以后,会在生成默认拦截器时,将allowed-origins的值注入,这样就可以解决访问时出现403的错误。

注:也可以通过写配置类的方式,不过其他人都写得很详细了,在这里就不在多说。更加详细的说明请见springmvc官方文档,上面写得很清楚,这里贴出来仅仅是因为自己还不是很熟悉,官方文档写道很清楚的。

你可能感兴趣的:(spring的websocket访问时403)