1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

API: Support HTTP basic authentication for API. v6.0.4, v5.0.152 (#3458)

Co-authored-by: winlin <winlin@vip.126.com>
Co-authored-by: john <hondaxiao@tencent.com>
This commit is contained in:
Haibo Chen 2023-04-01 12:45:29 +08:00 committed by GitHub
parent 571043ff3d
commit 771ae0a1a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 660 additions and 50 deletions

View file

@ -3639,7 +3639,7 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5)
if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen xxx;crossdomain off;raw_api {enabled on;allow_reload on;allow_query on;allow_update on;}}"));
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "http_api{enabled on;listen xxx;crossdomain off;auth {enabled on;username admin;password 123456;}raw_api {enabled on;allow_reload on;allow_query on;allow_update on;}}"));
EXPECT_TRUE(conf.get_http_api_enabled());
EXPECT_STREQ("xxx", conf.get_http_api_listen().c_str());
EXPECT_FALSE(conf.get_http_api_crossdomain());
@ -3647,6 +3647,9 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5)
EXPECT_TRUE(conf.get_raw_api_allow_reload());
EXPECT_FALSE(conf.get_raw_api_allow_query()); // Always disabled
EXPECT_FALSE(conf.get_raw_api_allow_update()); // Always disabled
EXPECT_TRUE(conf.get_http_api_auth_enabled());
EXPECT_STREQ("admin", conf.get_http_api_auth_username().c_str());
EXPECT_STREQ("123456", conf.get_http_api_auth_password().c_str());
}
if (true) {
@ -4112,6 +4115,15 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesHttpApi)
SrsSetEnvConfig(http_api_crossdomain, "SRS_HTTP_API_CROSSDOMAIN", "off");
EXPECT_FALSE(conf.get_http_api_crossdomain());
SrsSetEnvConfig(http_api_auth_enabled, "SRS_HTTP_API_AUTH_ENABLED", "on");
EXPECT_TRUE(conf.get_http_api_auth_enabled());
SrsSetEnvConfig(http_api_auth_username, "SRS_HTTP_API_AUTH_USERNAME", "admin");
EXPECT_STREQ("admin", conf.get_http_api_auth_username().c_str());
SrsSetEnvConfig(http_api_auth_password, "SRS_HTTP_API_AUTH_PASSWORD", "123456");
EXPECT_STREQ("123456", conf.get_http_api_auth_password().c_str());
}
if (true) {

View file

@ -1059,11 +1059,10 @@ VOID TEST(ProtocolHTTPTest, HTTPServerMuxerCORS)
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
HELPER_ASSERT_SUCCESS(r.set_url("/index.html", false));
SrsHttpCorsMux cs;
HELPER_ASSERT_SUCCESS(cs.initialize(&s, true));
SrsHttpCorsMux cs(&s);
HELPER_ASSERT_SUCCESS(cs.initialize(true));
HELPER_ASSERT_SUCCESS(cs.serve_http(&w, &r));
__MOCK_HTTP_EXPECT_STREQ(200, "Hello, world!", w);
}
// If CORS enabled, response OPTIONS with ok
@ -1079,8 +1078,8 @@ VOID TEST(ProtocolHTTPTest, HTTPServerMuxerCORS)
r.set_basic(HTTP_REQUEST, HTTP_OPTIONS, (http_status)200, -1);
HELPER_ASSERT_SUCCESS(r.set_url("/index.html", false));
SrsHttpCorsMux cs;
HELPER_ASSERT_SUCCESS(cs.initialize(&s, true));
SrsHttpCorsMux cs(&s);
HELPER_ASSERT_SUCCESS(cs.initialize(true));
HELPER_ASSERT_SUCCESS(cs.serve_http(&w, &r));
__MOCK_HTTP_EXPECT_STREQ(200, "", w);
@ -1099,11 +1098,10 @@ VOID TEST(ProtocolHTTPTest, HTTPServerMuxerCORS)
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
HELPER_ASSERT_SUCCESS(r.set_url("/index.html", false));
SrsHttpCorsMux cs;
HELPER_ASSERT_SUCCESS(cs.initialize(&s, false));
SrsHttpCorsMux cs(&s);
HELPER_ASSERT_SUCCESS(cs.initialize(false));
HELPER_ASSERT_SUCCESS(cs.serve_http(&w, &r));
__MOCK_HTTP_EXPECT_STREQ(200, "Hello, world!", w);
}
// If CORS not enabled, response error for options.
@ -1119,8 +1117,8 @@ VOID TEST(ProtocolHTTPTest, HTTPServerMuxerCORS)
r.set_basic(HTTP_REQUEST, HTTP_OPTIONS, (http_status)200, -1);
HELPER_ASSERT_SUCCESS(r.set_url("/index.html", false));
SrsHttpCorsMux cs;
HELPER_ASSERT_SUCCESS(cs.initialize(&s, false));
SrsHttpCorsMux cs(&s);
HELPER_ASSERT_SUCCESS(cs.initialize(false));
HELPER_ASSERT_SUCCESS(cs.serve_http(&w, &r));
__MOCK_HTTP_EXPECT_STREQ(405, "", w);
@ -1137,10 +1135,253 @@ VOID TEST(ProtocolHTTPTest, HTTPServerMuxerCORS)
SrsHttpMessage r(NULL, NULL);
HELPER_ASSERT_SUCCESS(r.set_url("/index.html", false));
SrsHttpCorsMux cs;
HELPER_ASSERT_SUCCESS(cs.initialize(&s, true));
SrsHttpCorsMux cs(&s);
HELPER_ASSERT_SUCCESS(cs.initialize(true));
HELPER_ASSERT_SUCCESS(cs.serve_http(&w, &r));
}
}
VOID TEST(ProtocolHTTPTest, HTTPServerMuxerAuth)
{
srs_error_t err;
if (true) {
SrsHttpServeMux s;
HELPER_ASSERT_SUCCESS(s.initialize());
MockHttpHandler* hroot = new MockHttpHandler("Hello, world!");
HELPER_ASSERT_SUCCESS(s.handle("/", hroot));
MockResponseWriter w;
SrsHttpMessage r(NULL, NULL);
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
SrsHttpHeader h ;
h.set("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin
r.set_header(&h, false);
HELPER_ASSERT_SUCCESS(r.set_url("/index.html", false));
SrsHttpAuthMux auth(&s);
HELPER_ASSERT_SUCCESS(auth.initialize(true, "admin", "admin"));
HELPER_ASSERT_SUCCESS(auth.serve_http(&w, &r));
__MOCK_HTTP_EXPECT_STREQ(200, "Hello, world!", w);
}
// incorrect token
if (true) {
SrsHttpServeMux s;
HELPER_ASSERT_SUCCESS(s.initialize());
MockHttpHandler* hroot = new MockHttpHandler("Hello, world!");
HELPER_ASSERT_SUCCESS(s.handle("/", hroot));
MockResponseWriter w;
SrsHttpMessage r(NULL, NULL);
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
SrsHttpHeader h ;
h.set("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin
r.set_header(&h, false);
HELPER_ASSERT_SUCCESS(r.set_url("/api/v1/clients/", false));
SrsHttpAuthMux auth(&s);
HELPER_ASSERT_SUCCESS(auth.initialize(true, "admin", "123456"));
HELPER_ASSERT_SUCCESS(auth.serve_http(&w, &r));
EXPECT_EQ(401, w.w->status);
}
// incorrect token, duplicate Basic
if (true) {
SrsHttpServeMux s;
HELPER_ASSERT_SUCCESS(s.initialize());
MockHttpHandler* hroot = new MockHttpHandler("Hello, world!");
HELPER_ASSERT_SUCCESS(s.handle("/", hroot));
MockResponseWriter w;
SrsHttpMessage r(NULL, NULL);
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
SrsHttpHeader h ;
h.set("Authorization", "Basic BasicYWRtaW46YWRtaW4="); // duplicate 'Basic'
r.set_header(&h, false);
HELPER_ASSERT_SUCCESS(r.set_url("/api/v1/clients/", false));
SrsHttpAuthMux auth(&s);
HELPER_ASSERT_SUCCESS(auth.initialize(true, "admin", "admin"));
HELPER_ASSERT_SUCCESS(auth.serve_http(&w, &r));
EXPECT_EQ(401, w.w->status);
}
// Authorization NOT start with 'Basic '
if (true) {
SrsHttpServeMux s;
HELPER_ASSERT_SUCCESS(s.initialize());
MockHttpHandler* hroot = new MockHttpHandler("Hello, world!");
HELPER_ASSERT_SUCCESS(s.handle("/", hroot));
MockResponseWriter w;
SrsHttpMessage r(NULL, NULL);
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
SrsHttpHeader h ;
h.set("Authorization", "YWRtaW46YWRtaW4="); // admin:admin
r.set_header(&h, false);
HELPER_ASSERT_SUCCESS(r.set_url("/api/v1/clients/", false));
SrsHttpAuthMux auth(&s);
HELPER_ASSERT_SUCCESS(auth.initialize(true, "admin", "admin"));
HELPER_ASSERT_SUCCESS(auth.serve_http(&w, &r));
EXPECT_EQ(401, w.w->status);
}
// NOT base64
if (true) {
SrsHttpServeMux s;
HELPER_ASSERT_SUCCESS(s.initialize());
MockHttpHandler* hroot = new MockHttpHandler("Hello, world!");
HELPER_ASSERT_SUCCESS(s.handle("/", hroot));
MockResponseWriter w;
SrsHttpMessage r(NULL, NULL);
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
SrsHttpHeader h ;
h.set("Authorization", "Basic admin:admin"); // admin:admin
r.set_header(&h, false);
HELPER_ASSERT_SUCCESS(r.set_url("/api/v1/clients/", false));
SrsHttpAuthMux auth(&s);
HELPER_ASSERT_SUCCESS(auth.initialize(true, "admin", "admin"));
HELPER_ASSERT_SUCCESS(auth.serve_http(&w, &r));
EXPECT_EQ(401, w.w->status);
}
// empty Authorization
if (true) {
SrsHttpServeMux s;
HELPER_ASSERT_SUCCESS(s.initialize());
MockHttpHandler* hroot = new MockHttpHandler("Hello, world!");
HELPER_ASSERT_SUCCESS(s.handle("/", hroot));
MockResponseWriter w;
SrsHttpMessage r(NULL, NULL);
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
HELPER_ASSERT_SUCCESS(r.set_url("/api/v1/clients/", false));
SrsHttpAuthMux auth(&s);
HELPER_ASSERT_SUCCESS(auth.initialize(true, "admin", "admin"));
HELPER_ASSERT_SUCCESS(auth.serve_http(&w, &r));
EXPECT_EQ(401, w.w->status);
}
// auth disabled, response with 200 ok, even though empty Authorization
if (true) {
SrsHttpServeMux s;
HELPER_ASSERT_SUCCESS(s.initialize());
MockHttpHandler* hroot = new MockHttpHandler("Hello, world!");
HELPER_ASSERT_SUCCESS(s.handle("/", hroot));
MockResponseWriter w;
SrsHttpMessage r(NULL, NULL);
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
HELPER_ASSERT_SUCCESS(r.set_url("/api/v1/clients/", false));
SrsHttpAuthMux auth(&s);
HELPER_ASSERT_SUCCESS(auth.initialize(false, "admin", "admin"));
HELPER_ASSERT_SUCCESS(auth.serve_http(&w, &r));
__MOCK_HTTP_EXPECT_STREQ(200, "Hello, world!", w);
}
// auth disabled, response with 200 ok, even though wrong token
if (true) {
SrsHttpServeMux s;
HELPER_ASSERT_SUCCESS(s.initialize());
MockHttpHandler* hroot = new MockHttpHandler("Hello, world!");
HELPER_ASSERT_SUCCESS(s.handle("/", hroot));
MockResponseWriter w;
SrsHttpMessage r(NULL, NULL);
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
SrsHttpHeader h ;
h.set("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin
r.set_header(&h, false);
HELPER_ASSERT_SUCCESS(r.set_url("/api/v1/clients/", false));
SrsHttpAuthMux auth(&s);
HELPER_ASSERT_SUCCESS(auth.initialize(false, "admin", "123456"));
HELPER_ASSERT_SUCCESS(auth.serve_http(&w, &r));
__MOCK_HTTP_EXPECT_STREQ(200, "Hello, world!", w);
}
// always response with 200 ok, for /rtc/*/
if (true) {
SrsHttpServeMux s;
HELPER_ASSERT_SUCCESS(s.initialize());
MockHttpHandler* hroot = new MockHttpHandler("Hello, world!");
HELPER_ASSERT_SUCCESS(s.handle("/", hroot));
MockResponseWriter w;
SrsHttpMessage r(NULL, NULL);
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
SrsHttpHeader h ;
h.set("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin
r.set_header(&h, false);
HELPER_ASSERT_SUCCESS(r.set_url("/rtc/play/", false));
SrsHttpAuthMux auth(&s);
HELPER_ASSERT_SUCCESS(auth.initialize(false, "admin", "123456"));
HELPER_ASSERT_SUCCESS(auth.serve_http(&w, &r));
__MOCK_HTTP_EXPECT_STREQ(200, "Hello, world!", w);
}
// always response with 200 ok, for /rtc/*/
if (true) {
SrsHttpServeMux s;
HELPER_ASSERT_SUCCESS(s.initialize());
MockHttpHandler* hroot = new MockHttpHandler("Hello, world!");
HELPER_ASSERT_SUCCESS(s.handle("/", hroot));
MockResponseWriter w;
SrsHttpMessage r(NULL, NULL);
r.set_basic(HTTP_REQUEST, HTTP_POST, (http_status)200, -1);
SrsHttpHeader h ;
h.set("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin
r.set_header(&h, false);
HELPER_ASSERT_SUCCESS(r.set_url("/index.html", false));
SrsHttpAuthMux auth(&s);
HELPER_ASSERT_SUCCESS(auth.initialize(false, "admin", "123456"));
HELPER_ASSERT_SUCCESS(auth.serve_http(&w, &r));
__MOCK_HTTP_EXPECT_STREQ(200, "Hello, world!", w);
}
}

View file

@ -6209,4 +6209,33 @@ VOID TEST(KernelUtilityTest, CoverCheckIPAddrValid)
ASSERT_FALSE(srs_check_ip_addr_valid("2001:0db8:85a3:0:0:8A2E:0370:7334:"));
#endif
ASSERT_FALSE(srs_check_ip_addr_valid("1e1.4.5.6"));
}
VOID TEST(KernelUtilityTest, Base64Decode)
{
srs_error_t err = srs_success;
if (true) {
string plaintext;
HELPER_EXPECT_SUCCESS(srs_av_base64_decode("YWRtaW46YWRtaW4=", plaintext));
EXPECT_STREQ("admin:admin", plaintext.c_str());
}
if (true) {
string plaintext;
HELPER_EXPECT_SUCCESS(srs_av_base64_decode("YWRtaW46MTIzNDU2", plaintext));
EXPECT_STREQ("admin:123456", plaintext.c_str());
}
if (true) {
string plaintext;
HELPER_EXPECT_SUCCESS(srs_av_base64_decode("YWRtaW46MTIzNDU2", plaintext));
EXPECT_STRNE("admin:admin", plaintext.c_str());
}
if (true) {
string plaintext;
HELPER_EXPECT_FAILED(srs_av_base64_decode("YWRtaW46YWRtaW", plaintext));
EXPECT_STRNE("admin:admin", plaintext.c_str());
}
}