Skip to content

Commit c57a4c1

Browse files
committed
add HTTP Basic Authorization to WS Client and Server
see: #55
1 parent 2d87bfa commit c57a4c1

File tree

6 files changed

+106
-2
lines changed

6 files changed

+106
-2
lines changed

examples/WebSocketClient/WebSocketClient.ino

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ void setup() {
7777
}
7878

7979
webSocket.begin("192.168.0.123", 81);
80+
//webSocket.setAuthorization("user", "Password"); // HTTP Basic Authorization
8081
webSocket.onEvent(webSocketEvent);
8182

8283
}

src/WebSockets.h

+2
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ typedef struct {
180180
uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer
181181
WSMessageHeader_t cWsHeaderDecode;
182182

183+
String base64Authorization; ///< Base64 encoded Auth request
184+
183185
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
184186
String cHttpLine; ///< HTTP header lines
185187
#endif

src/WebSocketsClient.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "WebSockets.h"
2626
#include "WebSocketsClient.h"
2727

28+
2829
WebSocketsClient::WebSocketsClient() {
2930
_cbEvent = NULL;
3031
_client.num = 0;
@@ -60,6 +61,7 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url,
6061
_client.cProtocol = protocol;
6162
_client.cExtensions = "";
6263
_client.cVersion = 0;
64+
_client.base64Authorization = "";
6365

6466
#ifdef ESP8266
6567
randomSeed(RANDOM_REG32);
@@ -202,6 +204,30 @@ void WebSocketsClient::disconnect(void) {
202204
}
203205
}
204206

207+
/**
208+
* set the Authorizatio for the http request
209+
* @param user const char *
210+
* @param password const char *
211+
*/
212+
void WebSocketsClient::setAuthorization(const char * user, const char * password) {
213+
if(user && password) {
214+
String auth = user;
215+
auth += ":";
216+
auth += password;
217+
_client.base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length());
218+
}
219+
}
220+
221+
/**
222+
* set the Authorizatio for the http request
223+
* @param auth const char * base64
224+
*/
225+
void WebSocketsClient::setAuthorization(const char * auth) {
226+
if(auth) {
227+
_client.base64Authorization = auth;
228+
}
229+
}
230+
205231
//#################################################################################
206232
//#################################################################################
207233
//#################################################################################
@@ -374,6 +400,10 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
374400
handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n";
375401
}
376402

403+
if(client->base64Authorization.length() > 0) {
404+
handshake += "Authorization: Basic " + client->base64Authorization + "\r\n";
405+
}
406+
377407
handshake += "\r\n";
378408

379409
client->tcp->write(handshake.c_str(), handshake.length());

src/WebSocketsClient.h

+3
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ class WebSocketsClient: private WebSockets {
6868

6969
void disconnect(void);
7070

71+
void setAuthorization(const char * user, const char * password);
72+
void setAuthorization(const char * auth);
73+
7174
protected:
7275
String _host;
7376
uint16_t _port;

src/WebSocketsServer.cpp

+45
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ void WebSocketsServer::begin(void) {
8080
client->cIsUpgrade = false;
8181
client->cIsWebsocket = false;
8282

83+
client->base64Authorization = "";
84+
8385
client->cWsRXsize = 0;
8486
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
8587
client->cHttpLine = "";
@@ -262,6 +264,32 @@ void WebSocketsServer::disconnect(uint8_t num) {
262264
}
263265
}
264266

267+
268+
269+
/**
270+
* set the Authorizatio for the http request
271+
* @param user const char *
272+
* @param password const char *
273+
*/
274+
void WebSocketsServer::setAuthorization(const char * user, const char * password) {
275+
if(user && password) {
276+
String auth = user;
277+
auth += ":";
278+
auth += password;
279+
_base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length());
280+
}
281+
}
282+
283+
/**
284+
* set the Authorizatio for the http request
285+
* @param auth const char * base64
286+
*/
287+
void WebSocketsServer::setAuthorization(const char * auth) {
288+
if(auth) {
289+
_base64Authorization = auth;
290+
}
291+
}
292+
265293
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
266294
/**
267295
* get an IP for a client
@@ -564,6 +592,8 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
564592
client->cProtocol = headerValue;
565593
} else if(headerName.equalsIgnoreCase("Sec-WebSocket-Extensions")) {
566594
client->cExtensions = headerValue;
595+
} else if(headerName.equalsIgnoreCase("Authorization")) {
596+
client->base64Authorization = headerValue;
567597
}
568598
} else {
569599
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str());
@@ -583,6 +613,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
583613
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cProtocol: %s\n", client->num, client->cProtocol.c_str());
584614
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cExtensions: %s\n", client->num, client->cExtensions.c_str());
585615
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cVersion: %d\n", client->num, client->cVersion);
616+
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - base64Authorization: %s\n", client->num, client->base64Authorization);
586617

587618
bool ok = (client->cIsUpgrade && client->cIsWebsocket);
588619

@@ -598,6 +629,20 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) {
598629
}
599630
}
600631

632+
if(_base64Authorization.length() > 0) {
633+
if(client->base64Authorization.length() > 0) {
634+
String auth = "Basic ";
635+
auth += _base64Authorization;
636+
if(auth != client->base64Authorization) {
637+
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num);
638+
handleAuthorizationFailed(client);
639+
return;
640+
}
641+
} else {
642+
ok = false;
643+
}
644+
}
645+
601646
if(ok) {
602647

603648
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incoming.\n", client->num);

src/WebSocketsServer.h

+25-2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ class WebSocketsServer: private WebSockets {
7878
void disconnect(void);
7979
void disconnect(uint8_t num);
8080

81+
void setAuthorization(const char * user, const char * password);
82+
void setAuthorization(const char * auth);
83+
8184
#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
8285
IPAddress remoteIP(uint8_t num);
8386
#endif
@@ -86,6 +89,7 @@ class WebSocketsServer: private WebSockets {
8689
uint16_t _port;
8790
String _origin;
8891
String _protocol;
92+
String _base64Authorization; ///< Base64 encoded Auth request
8993

9094
WEBSOCKETS_NETWORK_SERVER_CLASS * _server;
9195

@@ -109,8 +113,8 @@ class WebSocketsServer: private WebSockets {
109113

110114

111115
/**
112-
* called if a non Websocket connection is comming in.
113-
* Note: can be overrided
116+
* called if a non Websocket connection is coming in.
117+
* Note: can be override
114118
* @param client WSclient_t * ptr to the client struct
115119
*/
116120
virtual void handleNonWebsocketConnection(WSclient_t * client) {
@@ -126,6 +130,25 @@ class WebSocketsServer: private WebSockets {
126130
clientDisconnect(client);
127131
}
128132

133+
/**
134+
* called if a non Authorization connection is coming in.
135+
* Note: can be override
136+
* @param client WSclient_t * ptr to the client struct
137+
*/
138+
virtual void handleAuthorizationFailed(WSclient_t *client) {
139+
140+
client->tcp->write("HTTP/1.1 401 Unauthorized\r\n"
141+
"Server: arduino-WebSocket-Server\r\n"
142+
"Content-Type: text/plain\r\n"
143+
"Content-Length: 45\r\n"
144+
"Connection: close\r\n"
145+
"Sec-WebSocket-Version: 13\r\n"
146+
"WWW-Authenticate: Basic realm=\"WebSocket Server\""
147+
"\r\n"
148+
"This Websocket server requires Authorization!");
149+
clientDisconnect(client);
150+
}
151+
129152
/**
130153
* called for sending a Event to the app
131154
* @param num uint8_t

0 commit comments

Comments
 (0)