Auto login on every ws/rpc connection. Use HTTP Authorization header information if present

This commit is contained in:
elmato 2017-01-27 07:41:23 +00:00
parent adf288b4ad
commit 77645d889f

View file

@ -46,10 +46,12 @@
#include <fc/rpc/api_connection.hpp>
#include <fc/rpc/websocket_api.hpp>
#include <fc/network/resolve.hpp>
#include <fc/crypto/base64.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/signals2.hpp>
#include <boost/range/algorithm/reverse.hpp>
#include <boost/algorithm/string.hpp>
#include <iostream>
@ -232,21 +234,46 @@ namespace detail {
FC_CAPTURE_AND_RETHROW((endpoint_string))
}
void new_connection( const fc::http::websocket_connection_ptr& c )
{
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(*c);
auto login = std::make_shared<graphene::app::login_api>( std::ref(*_self) );
login->enable_api("database_api");
wsc->register_api(login->database());
wsc->register_api(fc::api<graphene::app::login_api>(login));
c->set_session_data( wsc );
std::string username = "*";
std::string password = "*";
// Try to extract login information from "Authorization" header if present
std::string auth = c->get_request_header("Authorization");
if( boost::starts_with(auth, "Basic ") ) {
FC_ASSERT( auth.size() > 6 );
auto user_pass = fc::base64_decode(auth.substr(6));
std::vector<std::string> parts;
boost::split( parts, user_pass, boost::is_any_of(":") );
FC_ASSERT(parts.size() == 2);
username = parts[0];
password = parts[1];
}
login->login(username, password);
}
void reset_websocket_server()
{ try {
if( !_options->count("rpc-endpoint") )
return;
_websocket_server = std::make_shared<fc::http::websocket_server>();
_websocket_server->on_connection( std::bind(&application_impl::new_connection, this, std::placeholders::_1) );
_websocket_server->on_connection([&]( const fc::http::websocket_connection_ptr& c ){
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(*c);
auto login = std::make_shared<graphene::app::login_api>( std::ref(*_self) );
auto db_api = std::make_shared<graphene::app::database_api>( std::ref(*_self->chain_database()) );
wsc->register_api(fc::api<graphene::app::database_api>(db_api));
wsc->register_api(fc::api<graphene::app::login_api>(login));
c->set_session_data( wsc );
});
ilog("Configured websocket rpc to listen on ${ip}", ("ip",_options->at("rpc-endpoint").as<string>()));
_websocket_server->listen( fc::ip::endpoint::from_string(_options->at("rpc-endpoint").as<string>()) );
_websocket_server->start_accept();
@ -265,15 +292,8 @@ namespace detail {
string password = _options->count("server-pem-password") ? _options->at("server-pem-password").as<string>() : "";
_websocket_tls_server = std::make_shared<fc::http::websocket_tls_server>( _options->at("server-pem").as<string>(), password );
_websocket_tls_server->on_connection( std::bind(&application_impl::new_connection, this, std::placeholders::_1) );
_websocket_tls_server->on_connection([&]( const fc::http::websocket_connection_ptr& c ){
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(*c);
auto login = std::make_shared<graphene::app::login_api>( std::ref(*_self) );
auto db_api = std::make_shared<graphene::app::database_api>( std::ref(*_self->chain_database()) );
wsc->register_api(fc::api<graphene::app::database_api>(db_api));
wsc->register_api(fc::api<graphene::app::login_api>(login));
c->set_session_data( wsc );
});
ilog("Configured websocket TLS rpc to listen on ${ip}", ("ip",_options->at("rpc-tls-endpoint").as<string>()));
_websocket_tls_server->listen( fc::ip::endpoint::from_string(_options->at("rpc-tls-endpoint").as<string>()) );
_websocket_tls_server->start_accept();