0

I am trying to add a websocket endpoint to a Struts 2 + Spring Framework 4.29 web application deployed on a WebLogic 12.2 server that has to listen for text and binary data from a network scanner. But when I try to connect to the endpoint, I just receive a 401 status code:

Using wscat:

wscat --connect ws://localhost:7001/gestAcredPrensa/escaner
error: Unexpected server response: 401

Using Python, it sends the typical 401 default page back:

>>> import websocket
>>> ws = websocket.WebSocket()
>>> ws.connect('ws://localhost:7001/gestAcredPrensa/escaner')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\websocket\_core.py", line 261, in connect
    self.handshake_response = handshake(self.sock, url, *addrs, **options)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\websocket\_handshake.py", line 65, in handshake
    status, resp = _get_resp_headers(sock)
                   ^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\websocket\_handshake.py", line 150, in _get_resp_headers
    raise WebSocketBadStatusException(
websocket._exceptions.WebSocketBadStatusException: Handshake status 401 Unauthorized -+-+- {'date': 'Mon, 01 Jul 2024 11:45:15 GMT', 'content-length': '1468', 'content-type': 'text/html; charset=UTF-8', 'www-authenticate': 'Basic realm="jazn.com"'} -+-+- b'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Draft//EN">\n<HTML>\n<HEAD>\n<TITLE>Error 401--Unauthorized</TITLE>\n</HEAD>\n<BODY bgcolor="white">\n<FONT FACE=Helvetica><BR CLEAR=all>\n<TABLE border=0 cellspacing=5><TR><TD><BR CLEAR=all>\n<FONT FACE="Helvetica" COLOR="black" SIZE="3"><H2>Error 401--Unauthorized</H2>\n</FONT></TD></TR>\n</TABLE>\n<TABLE border=0 width=100% cellpadding=10><TR><TD VALIGN=top WIDTH=100% BGCOLOR=white><FONT FACE="Courier New"><FONT FACE="Helvetica" SIZE="3"><H3>From RFC 2068 <i>Hypertext Transfer Protocol -- HTTP/1.1</i>:</H3>\n</FONT><FONT FACE="Helvetica" SIZE="3"><H4>10.4.2 401 Unauthorized</H4>\n</FONT><P><FONT FACE="Courier New">The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.46) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity MAY include relevant diagnostic information. HTTP access authentication is explained in section 11.</FONT></P>\n</FONT></TD></TR>\n</TABLE>\n\n</BODY>\n</HTML>\n'

This is my web socket configuration:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    private static final Logger log = Logger.getLogger(WebSocketConfig.class);

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        log.info("Registrando WebSocketHandlers");
        webSocketHandlerRegistry.addHandler(new EscanerHandler(), "/escaner").setAllowedOrigins("*");
        log.info("Se han registrado WebSocketHandlers");
    }

    @Bean
    public EscanerHandler escanerHandler() {
        return new EscanerHandler();
    }
}

and this is the test handler (those log messages are never emitted):

public class EscanerHandler implements WebSocketHandler {
    private static final Logger log = Logger.getLogger(EscanerHandler.class);

    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
        log.info("Conexión establecida");
    }

    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
        log.info("Llegó un mensaje: " + webSocketMessage.getPayload());
    }

    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
        log.error("Transport Error: " + throwable.getMessage(), throwable);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
        log.info("Conexión cerrada");
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}

I also disabled security for this URL (which is basic authentication) in applicationContext.xml:

<http pattern="/escaner/**" security="none" />

<http use-expressions="true" >
    <custom-filter ref="requestHeaderFilter" before="FORM_LOGIN_FILTER" />
    <csrf disabled="true"/>
    <intercept-url pattern="/escaner/**" access="permitAll" />
    <form-login login-page="/entrada" />
</http>

and configure Struts to ignore this URL:

<constant name="struts.action.excludePattern" value="^ws://.+\$"/>
<constant name="struts.action.excludePattern" value="/escaner/.*"/>

When deploying the web application, the logs show that the configuration is getting registered:

01 jul 2024 14:03:24,379  INFO FilterInvocationSecurityMetadataSourceParser:194 - Creating access control expression attribute 'permitAll' for /escaner/**

01 jul 2024 14:03:25,638  INFO DefaultSecurityFilterChain:43 - Creating filter chain: Ant [pattern='/escaner/**'], []

01 jul 2024 14:03:26,260  INFO WebSocketConfig:17 - Registrando WebSocketHandlers
01 jul 2024 14:03:26,262  INFO WebSocketConfig:19 - Se han registrado WebSocketHandlers
01 jul 2024 14:03:26,341  INFO WebSocketHandlerMapping:341 - Mapped URL path [/escaner] onto handler of type [class org.springframework.web.socket.server.support.WebSocketHttpRequestHandler]

There is nothing at all in the logs when I try to make a connection to the web socket.

0