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");
            ManagedList<? super Object> interceptors = WebSocketNamespaceUtils.parseBeanSubElements(interceptorsElement, context);
            String allowedOriginsAttribute = element.getAttribute("allowed-origins");
            List<String> allowedOrigins = Arrays.asList(StringUtils.tokenizeToStringArray(allowedOriginsAttribute, ","));
            interceptors.add(new OriginHandshakeInterceptor(allowedOrigins));
            strategy = new WebSocketHandlerMappingStrategy(handshakeHandler, interceptors);
        }

        ManagedMap<String, Object> urlMap = new ManagedMap<String, Object>();
        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官方文檔,上面寫得很清楚,這裏貼出來僅僅是因爲自己還不是很熟悉,官方文檔寫道很清楚的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章