beast icon indicating copy to clipboard operation
beast copied to clipboard

Basic Authentication example

Open AntonioL opened this issue 4 years ago • 20 comments

I understand boost::beast does not offer high-level API to increase likelihood of standardisation in future. And I wonder whether the community produced wrappesr around boost::beast for mundane tasks.

I apologise in advance if this does not belong to a github issue, please close it in the case.

AntonioL avatar Oct 13 '19 15:10 AntonioL

What high-level APIs did you have in mind?

vinniefalco avatar Oct 13 '19 15:10 vinniefalco

Something along the lines of Python requests for example.

I understand that such a higher-level API is not in the business to belong to boost::beast, this issue is more for double checking whether any other independent developer made an effort in building something similar. On github I cannot seem to find any.

AntonioL avatar Oct 13 '19 15:10 AntonioL

Something along the lines of Python requests for example.

Yeah that would be nice!

vinniefalco avatar Oct 13 '19 15:10 vinniefalco

Like this: https://github.com/expresscpp/expresscpp ?

gocarlos avatar Nov 29 '19 17:11 gocarlos

Nice!! Consider adding your project to this page?

https://github.com/boostorg/beast/wiki/Companies-and-Individuals-Using-Beast

vinniefalco avatar Nov 29 '19 18:11 vinniefalco

Thank you @gocarlos

I hope that this thread will receive some few more entries!

AntonioL avatar Dec 09 '19 20:12 AntonioL

Working on it: https://github.com/vinniefalco/url

vinniefalco avatar Dec 09 '19 21:12 vinniefalco

Working on it: https://github.com/vinniefalco/url

What is the plan? First, you design and implement. a facility which can represent an URL,. Second, you plug some high-level API inside beast taking the aformentioned representation?

Is my understanding correct?

AntonioL avatar Dec 10 '19 00:12 AntonioL

What is the plan?

Yes, the general idea is to work in layers. Asio is the bottom layer, the networking. Then we have Beast which implements low level HTTP and WebSocket. If we want to have a high-level HTTP client like Python Requests (which I think is a good goal!) then we need some other components:

  • URL Library
  • Library to get proxy configuration from the OS
  • SSL certificate verification lib
  • Refactored ZLib (to handle gzip and deflate Transfer-Encoding)
  • Basic Authentication module
  • Cookies module
  • OAuth2 library
  • "Secure" socket (i.e. a high-level boost::asio::ssl::stream)

And probably we will need a couple of other things along the way. I am figuring out how to get all of this going. If anyone wants to volunteer, I'm more than happy to have their help!

vinniefalco avatar Dec 10 '19 00:12 vinniefalco

I am willing to contribute to this project. I am new to open source contribution but I am willing to put in time and effort to make this happen. Please provide some guideline on getting started. Thanks!

swornim1 avatar Dec 21 '19 03:12 swornim1

Any idea what Basic Authentication might look like? Or cookies?

vinniefalco avatar Dec 21 '19 04:12 vinniefalco

I have an understanding of how basic authentication and cookies works, but I am not sure how the design and implementation will work yet? Do I have to turn in a proposal with the design and implementation details to move forward? Thanks!

swornim1 avatar Dec 22 '19 03:12 swornim1

Well, what I like to do is make a prototype of what the library would look like if it was used. Where I have some interfaces, but no implementatation, and then make a list of what use-cases I want to support. Then for each use-case I make a proposed syntax with sample code that shows what the syntax is like. Here's an example of that design process: https://github.com/boostorg/beast/issues/154

vinniefalco avatar Dec 22 '19 04:12 vinniefalco

basic_authentication_header can be used for constructing the basic authentication header from the provided username and password. encoded_header() returns the header after base64 encoding the username and password

    class basic_authentication_header
    {
	private:
		        string header_before_encoding;
		        string header_after_encoding;
        public:
		        basic_authentication_header(string username, string password);
		        void encode_header();
		        string encoded_header();
    };

basic_authentication handles the authentication on server side. The path of the file containing the username and password is initalized from the constructor, and later the authenticate function compares the username and password from the header file with the username and password in the files, and determine the validity of the requestor.

class basic_authentication
{
	private:
			string username_passwd_file_path;
			
	public:
			 basic_authentication(string username_passwd_file_path);
			 bool authenticate(string header);
};

Above is the prototype and a brief description of the functions. Please recommend required modifications. Is this the right way to approach the design process? Thank you!

swornim1 avatar Dec 25 '19 03:12 swornim1

There's a file? (Yes, this is a good design approach)

vinniefalco avatar Dec 25 '19 15:12 vinniefalco

I was thinking of a file which stores the username and password list like a .htpasswd file, which can be refered to while validating the basic authentication request.

swornim1 avatar Dec 26 '19 22:12 swornim1

I think having the file is a bit too high level, we need something in between first. Maybe the API can have the caller supply an invocable object that performs the check for the credentials? And the example can have something that uses .htaccess (but this example code won't be an official, public API)

vinniefalco avatar Dec 27 '19 02:12 vinniefalco

basic_auth

I took the above image from https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication website

As I was reading more about the basic authentication and through boost::beast::message and boost::beast:field library, I got more confused about implementing the basic authentication module. Initially I was thinking of a library that would help the users create the basic authentication header with username and password on the client side, and a function which would allow users to validate the basic authentication request on server side. Since the beast::message library allows the functionality to develop the basic authentication header for the user, I felt like I was going in the wrong direction. Could you please give some suggestion about what we are trying to accomplish with the basic authentication module? Thanks in advance!

swornim1 avatar Dec 28 '19 03:12 swornim1

Maybe first just write a simple example client program that does basic authentication against some well known server?

vinniefalco avatar Dec 28 '19 16:12 vinniefalco

For the server, I did an apache2 server setup on SUSE Linux Enterprise server running on AWS ec2 instance. I have setup two targets one with basic authentication enabled, and the other without the basic authentication.

Link for the target without basic authentication: 52.15.155.121/index.html

Link for the target with the basic authentication: 52.15.155.121/basic_auth_test/index.html

The credential for logging into the link with basic_auth_test are provided below:username: test Password: test

I verified from a web browser that the basic authentication mechanism is setup and working properly on the server.

For the client, I wrote the basic_auth_client by referring to the libs/beast/example/http/client/sync/http_client_sync.cpp example provided in boost::beast documentation. The client is able to fetch the request and recognize whether the response has basic authentication or not. After recognizing that the server requires authorization, the client updates the authorization field of the request header with the required value which in our case is "Basic test:test", after base64 encoding turns out to be "Basic dGVzdDp0ZXN0". The server checks the header and verifies the request and responds with the required document.

The link for the project is listed below: https://github.com/swornim1/test_server.git

swornim1 avatar Dec 30 '19 03:12 swornim1