Skip to content

Commit 332e059

Browse files
1995parhamigrr
authored andcommitted
ESP8266HTTPClient: add digest authentication example (#4112)
1 parent bd1c7ce commit 332e059

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
This sketch shows how to handle HTTP Digest Authorization.
3+
4+
Written by Parham Alvani and Sajjad Rahnama, 2018-01-07.
5+
6+
This example is released into public domain,
7+
or, at your option, CC0 licensed.
8+
*/
9+
10+
#include <ESP8266WiFi.h>
11+
12+
#include <ESP8266HTTPClient.h>
13+
14+
const char* ssid = "........";
15+
const char* ssidPassword = "........";
16+
17+
const char *username = "admin";
18+
const char *password = "admin";
19+
20+
const char *server = "http://httpbin.org";
21+
const char *uri = "/digest-auth/auth/admin/admin/MD5";
22+
23+
String exractParam(String& authReq, const String& param, const char delimit){
24+
int _begin = authReq.indexOf(param);
25+
if (_begin==-1) return "";
26+
return authReq.substring(_begin+param.length(),authReq.indexOf(delimit,_begin+param.length()));
27+
}
28+
29+
String getCNonce(const int len) {
30+
static const char alphanum[] =
31+
"0123456789"
32+
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
33+
"abcdefghijklmnopqrstuvwxyz";
34+
String s = "";
35+
36+
for (int i = 0; i < len; ++i) {
37+
s += alphanum[rand() % (sizeof(alphanum) - 1)];
38+
}
39+
40+
return s;
41+
}
42+
43+
String getDigestAuth(String& authReq, const String& username, const String& password, const String& uri, unsigned int counter) {
44+
// extracting required parameters for RFC 2069 simpler Digest
45+
String realm = exractParam(authReq, "realm=\"", '"');
46+
String nonce = exractParam(authReq, "nonce=\"", '"');
47+
String cNonce = getCNonce(8);
48+
49+
char nc[9];
50+
snprintf(nc, sizeof(nc), "%08x", counter);
51+
52+
// parameters for the RFC 2617 newer Digest
53+
MD5Builder md5;
54+
md5.begin();
55+
md5.add(username + ":" + realm + ":" + password); // md5 of the user:realm:user
56+
md5.calculate();
57+
String h1 = md5.toString();
58+
59+
md5.begin();
60+
md5.add(String("GET:") + uri);
61+
md5.calculate();
62+
String h2 = md5.toString();
63+
64+
md5.begin();
65+
md5.add(h1 + ":" + nonce + ":" + String(nc) + ":" + cNonce + ":" + "auth" + ":" + h2);
66+
md5.calculate();
67+
String response = md5.toString();
68+
69+
String authorization = "Digest username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce +
70+
"\", uri=\"" + uri + "\", algorithm=\"MD5\", qop=auth, nc=" + String(nc) + ", cnonce=\"" + cNonce + "\", response=\"" + response + "\"";
71+
Serial.println(authorization);
72+
73+
return authorization;
74+
}
75+
76+
void setup() {
77+
Serial.begin(9600);
78+
79+
WiFi.mode(WIFI_STA);
80+
WiFi.begin(ssid, ssidPassword);
81+
82+
while (WiFi.status() != WL_CONNECTED) {
83+
delay(500);
84+
Serial.print(".");
85+
}
86+
87+
Serial.println("");
88+
Serial.println("WiFi connected");
89+
Serial.println("IP address: ");
90+
Serial.println(WiFi.localIP());
91+
}
92+
93+
void loop() {
94+
HTTPClient http;
95+
96+
Serial.print("[HTTP] begin...\n");
97+
98+
// configure traged server and url
99+
http.begin(String(server) + String(uri));
100+
101+
102+
const char *keys[] = {"WWW-Authenticate"};
103+
http.collectHeaders(keys, 1);
104+
105+
Serial.print("[HTTP] GET...\n");
106+
// start connection and send HTTP header
107+
int httpCode = http.GET();
108+
109+
if (httpCode > 0) {
110+
String authReq = http.header("WWW-Authenticate");
111+
Serial.println(authReq);
112+
113+
String authorization = getDigestAuth(authReq, String(username), String(password), String(uri), 1);
114+
115+
http.end();
116+
http.begin(String(server) + String(uri));
117+
118+
http.addHeader("Authorization", authorization);
119+
120+
int httpCode = http.GET();
121+
if (httpCode > 0) {
122+
String payload = http.getString();
123+
Serial.println(payload);
124+
} else {
125+
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
126+
}
127+
} else {
128+
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
129+
}
130+
131+
http.end();
132+
delay(10000);
133+
}

0 commit comments

Comments
 (0)