123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- /**
- Implements HTTP Basic Auth.
- Copyright: © 2012 Sönke Ludwig
- License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file.
- Authors: Sönke Ludwig
- */
- module vibe.http.auth.basic_auth;
- import vibe.http.server;
- import vibe.core.log;
- import std.base64;
- import std.exception;
- import std.string;
- @safe:
- /**
- Returns a request handler that enforces request to be authenticated using HTTP Basic Auth.
- */
- HTTPServerRequestDelegateS performBasicAuth(string realm, PasswordVerifyCallback pwcheck)
- {
- void handleRequest(scope HTTPServerRequest req, scope HTTPServerResponse res)
- @safe {
- if (!checkBasicAuth(req, pwcheck)) {
- res.statusCode = HTTPStatus.unauthorized;
- res.contentType = "text/plain";
- res.headers["WWW-Authenticate"] = "Basic realm=\""~realm~"\"";
- res.bodyWriter.write("Authorization required");
- }
- }
- return &handleRequest;
- }
- /// Scheduled for deprecation - use a `@safe` callback instead.
- HTTPServerRequestDelegateS performBasicAuth(string realm, bool delegate(string, string) @system pwcheck)
- @system {
- return performBasicAuth(realm, (u, p) @trusted => pwcheck(u, p));
- }
- /**
- Enforces HTTP Basic Auth authentication on the given req/res pair.
- Params:
- req = Request object that is to be checked
- res = Response object that will be used for authentication errors
- realm = HTTP Basic Auth realm reported to the client
- pwcheck = A delegate queried for validating user/password pairs
- Returns: Returns the name of the authenticated user.
- 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 ")) {
- 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;
- return true;
- }
- }
- return false;
- }
- static import vibe.http.internal.basic_auth_client;
- alias addBasicAuth = vibe.http.internal.basic_auth_client.addBasicAuth;
- alias PasswordVerifyCallback = bool delegate(string user, string password);
|