HTTP Authentication Schemes #2089

This commit is contained in:
Günter Obiltschnig 2018-03-05 15:32:08 +01:00
parent 603a6e23da
commit d0f2253c51

View File

@ -26,7 +26,7 @@ using Poco::icompare;
using Poco::Ascii;
namespace
namespace
{
bool mustBeQuoted(const std::string& name)
{
@ -41,19 +41,19 @@ namespace
icompare(name, "uri") == 0 ||
icompare(name, "username") == 0;
}
void formatParameter(std::string& result, const std::string& name, const std::string& value)
{
result += name;
result += '=';
if (mustBeQuoted(name))
if (mustBeQuoted(name))
{
result += '"';
result += value;
result += '"';
}
else
}
else
{
result += value;
}
@ -119,7 +119,7 @@ void HTTPAuthenticationParams::fromRequest(const HTTPRequest& request)
request.getCredentials(scheme, authInfo);
if (icompare(scheme, "Digest") != 0)
if (icompare(scheme, "Digest") != 0)
throw InvalidArgumentException("Could not parse non-Digest authentication information", scheme);
fromAuthInfo(authInfo);
@ -136,16 +136,16 @@ void HTTPAuthenticationParams::fromResponse(const HTTPResponse& response, const
while (!found && it != response.end() && icompare(it->first, header) == 0)
{
const std::string& header = it->second;
if (icompare(header, 0, 6, "Basic ") == 0)
if (icompare(header, 0, 6, "Basic ") == 0)
{
parse(header.begin() + 6, header.end());
found = true;
}
}
else if (icompare(header, 0, 7, "Digest ") == 0)
{
parse(header.begin() + 7, header.end());
found = true;
}
}
++it;
}
if (!found) throw NotAuthenticatedException("No Basic or Digest authentication header found");
@ -169,13 +169,13 @@ std::string HTTPAuthenticationParams::toString() const
ConstIterator iter = begin();
std::string result;
if (iter != end())
if (iter != end())
{
formatParameter(result, iter->first, iter->second);
++iter;
}
for (; iter != end(); ++iter)
for (; iter != end(); ++iter)
{
result.append(", ");
formatParameter(result, iter->first, iter->second);
@ -187,7 +187,7 @@ std::string HTTPAuthenticationParams::toString() const
void HTTPAuthenticationParams::parse(std::string::const_iterator first, std::string::const_iterator last)
{
enum State
enum State
{
STATE_INITIAL = 0x0100,
STATE_FINAL = 0x0200,
@ -205,61 +205,61 @@ void HTTPAuthenticationParams::parse(std::string::const_iterator first, std::str
std::string token;
std::string value;
for (std::string::const_iterator it = first; it != last; ++it)
for (std::string::const_iterator it = first; it != last; ++it)
{
switch (state)
switch (state)
{
case STATE_SPACE:
if (Ascii::isAlphaNumeric(*it) || *it == '_')
if (Ascii::isAlphaNumeric(*it) || *it == '_' || *it == '-')
{
token += *it;
state = STATE_TOKEN;
}
else if (Ascii::isSpace(*it))
}
else if (Ascii::isSpace(*it))
{
// Skip
}
}
else throw SyntaxException("Invalid authentication information");
break;
case STATE_TOKEN:
if (*it == '=')
if (*it == '=')
{
state = STATE_EQUALS;
}
else if (Ascii::isAlphaNumeric(*it) || *it == '_')
}
else if (Ascii::isAlphaNumeric(*it) || *it == '_' || *it == '-')
{
token += *it;
}
}
else throw SyntaxException("Invalid authentication information");
break;
case STATE_EQUALS:
if (Ascii::isAlphaNumeric(*it) || *it == '_')
if (Ascii::isAlphaNumeric(*it) || *it == '_')
{
value += *it;
state = STATE_VALUE;
}
else if (*it == '"')
}
else if (*it == '"')
{
state = STATE_VALUE_QUOTED;
}
}
else throw SyntaxException("Invalid authentication information");
break;
case STATE_VALUE_QUOTED:
if (*it == '\\')
if (*it == '\\')
{
state = STATE_VALUE_ESCAPE;
}
else if (*it == '"')
}
else if (*it == '"')
{
add(token, value);
token.clear();
value.clear();
state = STATE_COMMA;
}
else
}
else
{
value += *it;
}
@ -271,21 +271,21 @@ void HTTPAuthenticationParams::parse(std::string::const_iterator first, std::str
break;
case STATE_VALUE:
if (Ascii::isSpace(*it))
if (Ascii::isSpace(*it))
{
add(token, value);
token.clear();
value.clear();
state = STATE_COMMA;
}
else if (*it == ',')
}
else if (*it == ',')
{
add(token, value);
token.clear();
value.clear();
state = STATE_SPACE;
}
else
}
else
{
value += *it;
}
@ -295,11 +295,11 @@ void HTTPAuthenticationParams::parse(std::string::const_iterator first, std::str
if (*it == ',')
{
state = STATE_SPACE;
}
else if (Ascii::isSpace(*it))
}
else if (Ascii::isSpace(*it))
{
// Skip
}
}
else throw SyntaxException("Invalid authentication information");
break;
}