Auto login on every ws/rpc connection. Use HTTP Authorization header information if present
This commit is contained in:
parent
adf288b4ad
commit
77645d889f
1 changed files with 36 additions and 16 deletions
|
|
@ -46,10 +46,12 @@
|
||||||
#include <fc/rpc/api_connection.hpp>
|
#include <fc/rpc/api_connection.hpp>
|
||||||
#include <fc/rpc/websocket_api.hpp>
|
#include <fc/rpc/websocket_api.hpp>
|
||||||
#include <fc/network/resolve.hpp>
|
#include <fc/network/resolve.hpp>
|
||||||
|
#include <fc/crypto/base64.hpp>
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <boost/signals2.hpp>
|
#include <boost/signals2.hpp>
|
||||||
#include <boost/range/algorithm/reverse.hpp>
|
#include <boost/range/algorithm/reverse.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
@ -232,21 +234,46 @@ namespace detail {
|
||||||
FC_CAPTURE_AND_RETHROW((endpoint_string))
|
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()
|
void reset_websocket_server()
|
||||||
{ try {
|
{ try {
|
||||||
if( !_options->count("rpc-endpoint") )
|
if( !_options->count("rpc-endpoint") )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_websocket_server = std::make_shared<fc::http::websocket_server>();
|
_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>()));
|
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->listen( fc::ip::endpoint::from_string(_options->at("rpc-endpoint").as<string>()) );
|
||||||
_websocket_server->start_accept();
|
_websocket_server->start_accept();
|
||||||
|
|
@ -265,15 +292,8 @@ namespace detail {
|
||||||
|
|
||||||
string password = _options->count("server-pem-password") ? _options->at("server-pem-password").as<string>() : "";
|
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 = 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>()));
|
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->listen( fc::ip::endpoint::from_string(_options->at("rpc-tls-endpoint").as<string>()) );
|
||||||
_websocket_tls_server->start_accept();
|
_websocket_tls_server->start_accept();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue