10 #include <boost/algorithm/string.hpp>
11 #include <pion/algorithm.hpp>
12 #include <pion/http/basic_auth.hpp>
13 #include <pion/http/response_writer.hpp>
14 #include <pion/http/server.hpp>
23 const unsigned int basic_auth::CACHE_EXPIRATION = 300;
29 : http::
auth(userManager), m_realm(realm),
30 m_cache_cleanup_time(boost::posix_time::second_clock::universal_time())
32 set_logger(PION_GET_LOGGER(
"pion.http.basic_auth"));
41 boost::posix_time::ptime time_now(boost::posix_time::second_clock::universal_time());
42 if (time_now > m_cache_cleanup_time + boost::posix_time::seconds(CACHE_EXPIRATION)) {
44 boost::mutex::scoped_lock cache_lock(m_cache_mutex);
45 user_cache_type::iterator i;
46 user_cache_type::iterator next=m_user_cache.begin();
47 while (next!=m_user_cache.end()) {
50 if (time_now > i->second.first + boost::posix_time::seconds(CACHE_EXPIRATION)) {
52 m_user_cache.erase(i);
55 m_cache_cleanup_time = time_now;
59 std::string authorization = http_request_ptr->get_header(http::types::HEADER_AUTHORIZATION);
60 if (!authorization.empty()) {
61 std::string credentials;
64 boost::mutex::scoped_lock cache_lock(m_cache_mutex);
65 user_cache_type::iterator user_cache_ptr=m_user_cache.find(credentials);
66 if (user_cache_ptr!=m_user_cache.end()) {
69 http_request_ptr->set_user(user_cache_ptr->second.second);
70 user_cache_ptr->second.first = time_now;
82 m_user_cache.insert(std::make_pair(credentials, std::make_pair(time_now, user)));
84 http_request_ptr->set_user(user);
101 BOOST_THROW_EXCEPTION(
error::bad_arg() << error::errinfo_arg_name(name) );
106 if (!boost::algorithm::starts_with(authorization,
"Basic "))
108 credentials = authorization.substr(6);
109 if (credentials.empty())
115 std::string &username, std::string &password)
117 std::string user_password;
123 std::string::size_type i = user_password.find(
':');
124 if (i==0 || i==std::string::npos)
127 username = user_password.substr(0, i);
128 password = user_password.substr(i+1);
134 tcp::connection_ptr& tcp_conn)
137 static const std::string CONTENT =
138 " <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\""
139 "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">"
142 "<TITLE>Error</TITLE>"
143 "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=ISO-8859-1\">"
145 "<BODY><H1>401 Unauthorized.</H1></BODY>"
149 writer->get_response().set_status_code(http::types::RESPONSE_CODE_UNAUTHORIZED);
150 writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_UNAUTHORIZED);
151 writer->get_response().add_header(
"WWW-Authenticate",
"Basic realm=\"" + m_realm +
"\"");
152 writer->write_no_copy(CONTENT);
user_manager_ptr m_user_manager
container used to manager user objects
static bool parse_authorization(std::string const &authorization, std::string &credentials)
virtual bool handle_request(http::request_ptr &http_request_ptr, tcp::connection_ptr &tcp_conn)
void handle_unauthorized(http::request_ptr &http_request_ptr, tcp::connection_ptr &tcp_conn)
static bool base64_decode(std::string const &input, std::string &output)
void set_logger(logger log_ptr)
sets the logger to be used
static bool parse_credentials(std::string const &credentials, std::string &username, std::string &password)
exception thrown for an invalid configuration argument or option
basic_auth(user_manager_ptr userManager, const std::string &realm="PION")
default constructor
static boost::shared_ptr< response_writer > create(tcp::connection_ptr &tcp_conn, http::response_ptr &http_response_ptr, finished_handler_t handler=finished_handler_t())
virtual void set_option(const std::string &name, const std::string &value)
bool need_authentication(http::request_ptr const &http_request_ptr) const