espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.29k stars 7.2k forks source link

Authentication in http/ws server and https/wss server (IDFGH-5867) #7566

Open baldhead69 opened 2 years ago

baldhead69 commented 2 years ago

Hi,

I am trying to put a login(users and admin) in my Websocket Secure Server.

I am searching for a "full" secure method to iot authentication, maybe "Mutual authentication" or (Basic authentication is fine??!!).

I want to use https/wss in the server and i'm in doubt how to acomplish this.

Maybe login in the server before handshake is finished, ie, https, and if login is ok, switch to wss protocol.

Desirable features(at run time):

Thank's.

baldhead69 commented 2 years ago

@ESP-YJM,

If i send an http authentication header from my client websocket secure, can i extract that information ?

Or need to change the "esp_http_server" or "esp_https_server" components ?

Or add new functionality to "WebSocket" part in "Group: WebSocket" in "esp_http_server".

baldhead69 commented 2 years ago

@ESP-YJM

I tested and worked in "insecure mode". I tested and worked in "secure mode" too.

// config.transport_mode = HTTPD_SSL_TRANSPORT_INSECURE;
// config.transport_mode = HTTPD_SSL_TRANSPORT_SECURE;

static esp_err_t uri_handler(httpd_req_t *req)
{       
    ESP_LOGI(WSS_SERVER_TAG, LOG_USER("URI HANDLER:"));
    ESP_LOGI(WSS_SERVER_TAG, LOG_USER("req->method = %d\n"), req->method);

    if( req->method == HTTP_GET )
    {
        ESP_LOGI(WSS_SERVER_TAG, LOG_USER("Handshake done, the new connection was opened"));        
        int sockfd = httpd_req_to_sockfd(req);
        ESP_LOGI(WSS_SERVER_TAG, LOG_USER("Handshake Socket: %d\n"), sockfd);
//////
        size_t size = httpd_req_get_hdr_value_len(req, "Authorization");
        char val[50];
        esp_err_t err = httpd_req_get_hdr_value_str(req, "Authorization", val, 50);
        ESP_LOGI(WSS_SERVER_TAG, LOG_USER("header err: %s"), esp_err_to_name(err));        
        ESP_LOGI(WSS_SERVER_TAG, LOG_USER("header size: %d"), size);
        val[size] = '\0';
        ESP_LOGI(WSS_SERVER_TAG, LOG_USER("header value: %s\n"), val);
 /////
       return ESP_OK;
    }
}
diazmanuel commented 2 years ago

@ESP-YJM

I tested and worked in "insecure mode". I tested and worked in "secure mode" too.

// config.transport_mode = HTTPD_SSL_TRANSPORT_INSECURE;
// config.transport_mode = HTTPD_SSL_TRANSPORT_SECURE;

static esp_err_t uri_handler(httpd_req_t *req)
{       
    ESP_LOGI(WSS_SERVER_TAG, LOG_USER("URI HANDLER:"));
    ESP_LOGI(WSS_SERVER_TAG, LOG_USER("req->method = %d\n"), req->method);

    if( req->method == HTTP_GET )
    {
        ESP_LOGI(WSS_SERVER_TAG, LOG_USER("Handshake done, the new connection was opened"));        
        int sockfd = httpd_req_to_sockfd(req);
        ESP_LOGI(WSS_SERVER_TAG, LOG_USER("Handshake Socket: %d\n"), sockfd);
//////
        size_t size = httpd_req_get_hdr_value_len(req, "Authorization");
        char val[50];
        esp_err_t err = httpd_req_get_hdr_value_str(req, "Authorization", val, 50);
        ESP_LOGI(WSS_SERVER_TAG, LOG_USER("header err: %s"), esp_err_to_name(err));        
        ESP_LOGI(WSS_SERVER_TAG, LOG_USER("header size: %d"), size);
        val[size] = '\0';
        ESP_LOGI(WSS_SERVER_TAG, LOG_USER("header value: %s\n"), val);
 /////
       return ESP_OK;
    }
}

hi, did you manage to made a wss client with the basic authentification?

baldhead69 commented 2 years ago

Yes,

I haven't programmed the wss server for a while, I'm working on a driver now. I think I used okhttp lib.

diazmanuel commented 2 years ago

Yes,

I haven't programmed the wss server for a while, I'm working on a driver now. I think I used okhttp lib.

yes,me too ,but now iam trying to made a wss client with another esp32 or esp32s3 without success in the doc it said that do not support the basic auth "for now" (https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32s3/api-reference/protocols/esp_websocket_client.html#api-reference), actualy i try using the fields of username and password in the esp_websocket_client_config_t but they do not work maybe you already made a client for the esp32 (because whenever I have problems I look in the issues and a comment of yours appears solving it ) i will post a feature request with this, thanks you for your help :)

baldhead69 commented 2 years ago

I've never used "ESP WebSocket Client". I read in some place that "ESP WebSocket Client" is deprecated. I dont know why.

edit: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/migration-guides/removed-components.html

baldhead69 commented 2 years ago

@ESP-YJM,

Why "esp_websocket_client" is deprecated ???

https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/migration-guides/removed-components.html

diazmanuel commented 2 years ago

@ESP-YJM I wish to know too, why is the websocket client deprecated?

ESP-YJM commented 2 years ago

@baldhead69 @diazmanuel I think the esp_websocket_client is not deprecated, it was only migrated from IDF folder. User also can use it by https://components.espressif.com/component/espressif/esp_websocket_client. More and more components will be migrated from IDF and it can make IDF more concise and user can pick out their indeed components to use from https://components.espressif.com/.

ESP-YJM commented 1 year ago

Hi @baldhead69 , do you have any update for authentication in http/ws server and https/wss server?

baldhead69 commented 1 year ago

@ESP-YJM ,

No. I am not working on the server right now, but i used basic authentication i think.

mmb-davidsmith commented 1 year ago

This would be a useful feature not just for WSS, but also the HTTP server in general. I would think that taking a filter chain approach similar to some higher level frameworks would be very useful. This would essentially entail an ordered linked list of callbacks which could inspect, modify, etc. the request and response.

Ultimately I would suggest one before and after the URI handler as this could allow for a number of features to be handled generically, such as:

  1. Authentication (ie, filter which checks for Authentication header and if not set, sends a 401)
  2. Content Type transformation (eg, devices that support CBOR and JSON or such)
  3. Generalized Header Processing