Skip to content

Commit

Permalink
Merge pull request #1687 from rejectedsoftware/issue1449-basic-auth-s…
Browse files Browse the repository at this point in the history
…eparate

Add checkBasicAuth function. Fixes #1449.
  • Loading branch information
s-ludwig authored Feb 21, 2017
2 parents 9d0a75b + 7f5175a commit 1faa9db
Showing 1 changed file with 41 additions and 31 deletions.
72 changes: 41 additions & 31 deletions http/vibe/http/auth/basic_auth.d
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,12 @@ HTTPServerRequestDelegateS performBasicAuth(string realm, PasswordVerifyCallback
{
void handleRequest(scope HTTPServerRequest req, scope HTTPServerResponse res)
@safe {
auto pauth = "Authorization" in req.headers;

if( pauth && (*pauth).startsWith("Basic ") ){
string user_pw = () @trusted { return cast(string)Base64.decode((*pauth)[6 .. $]); } ();

auto idx = user_pw.indexOf(":");
enforceBadRequest(idx >= 0, "Invalid auth string format!");
string user = user_pw[0 .. idx];
string password = user_pw[idx+1 .. $];

if (pwcheck(user, password)) {
req.username = user;
// let the next stage handle the request
return;
}
if (!checkBasicAuth(req, pwcheck)) {
res.statusCode = HTTPStatus.unauthorized;
res.contentType = "text/plain";
res.headers["WWW-Authenticate"] = "Basic realm=\""~realm~"\"";
res.bodyWriter.write("Authorization required");
}

// else output an error page
res.statusCode = HTTPStatus.unauthorized;
res.contentType = "text/plain";
res.headers["WWW-Authenticate"] = "Basic realm=\""~realm~"\"";
res.bodyWriter.write("Authorization required");
}
return &handleRequest;
}
Expand All @@ -70,29 +54,55 @@ HTTPServerRequestDelegateS performBasicAuth(string realm, bool delegate(string,
Throws: Throws a HTTPStatusExeption in case of an authentication failure.
*/
string performBasicAuth(scope HTTPServerRequest req, scope HTTPServerResponse res, string realm, scope PasswordVerifyCallback pwcheck)
{
if (checkBasicAuth(req, pwcheck))
return req.username;

res.headers["WWW-Authenticate"] = "Basic realm=\""~realm~"\"";
throw new HTTPStatusException(HTTPStatus.unauthorized);
}
/// Scheduled for deprecation - use a `@safe` callback instead.
string performBasicAuth(scope HTTPServerRequest req, scope HTTPServerResponse res, string realm, scope bool delegate(string, string) @system pwcheck)
@system {
return performBasicAuth(req, res, realm, (u, p) @trusted => pwcheck(u, p));
}


/**
Checks for valid HTTP Basic Auth authentication on the given request.
Upon successful authorization, the name of the authorized user will
be stored in `req.username`.
Params:
req = Request object that is to be checked
pwcheck = A delegate queried for validating user/password pairs
Returns: Returns `true` $(I iff) a valid Basic Auth header is present
and the credentials were verified successfully by the validation
callback.
Throws: Throws a `HTTPStatusExeption` with `HTTPStatusCode.badRequest`
if the "Authorization" header is malformed.
*/
bool checkBasicAuth(scope HTTPServerRequest req, scope PasswordVerifyCallback pwcheck)
{
auto pauth = "Authorization" in req.headers;
if( pauth && (*pauth).startsWith("Basic ") ){
if (pauth && (*pauth).startsWith("Basic ")) {
string user_pw = () @trusted { return cast(string)Base64.decode((*pauth)[6 .. $]); } ();

auto idx = user_pw.indexOf(":");
enforceBadRequest(idx >= 0, "Invalid auth string format!");
string user = user_pw[0 .. idx];
string password = user_pw[idx+1 .. $];

if( pwcheck(user, password) ){
if (pwcheck(user, password)) {
req.username = user;
return user;
return true;
}
}

res.headers["WWW-Authenticate"] = "Basic realm=\""~realm~"\"";
throw new HTTPStatusException(HTTPStatus.unauthorized);
}
/// Scheduled for deprecation - use a `@safe` callback instead.
string performBasicAuth(scope HTTPServerRequest req, scope HTTPServerResponse res, string realm, scope bool delegate(string, string) @system pwcheck)
@system {
return performBasicAuth(req, res, realm, (u, p) @trusted => pwcheck(u, p));
return false;
}


Expand Down

0 comments on commit 1faa9db

Please sign in to comment.