bool HTTPCookieAuth::handleRequest(HTTPRequestPtr& request, TCPConnectionPtr& tcp_conn) { if (processLogin(request,tcp_conn)) { return false; // we processed login/logout request, no future processing for this request permitted } if (!needAuthentication(request)) { return true; // this request does not require authentication } // check if it is redirection page.. If yes, then do not test its credentials ( as used for login) if (!m_redirect.empty() && m_redirect==request->getResource()) { return true; // this request does not require authentication } // check cache for expiration PionDateTime time_now(boost::posix_time::second_clock::universal_time()); expireCache(time_now); // if we are here, we need to check if access authorized... const std::string auth_cookie(request->getCookie(AUTH_COOKIE_NAME)); if (! auth_cookie.empty()) { // check if this cookie is in user cache boost::mutex::scoped_lock cache_lock(m_cache_mutex); PionUserCache::iterator user_cache_itr=m_user_cache.find(auth_cookie); if (user_cache_itr != m_user_cache.end()) { // we find those credential in our cache... // we can approve authorization now! request->setUser(user_cache_itr->second.second); // and update cache timeout user_cache_itr->second.first = time_now; return true; } } // user not found handleUnauthorized(request,tcp_conn); return false; }
bool HTTPCookieAuth::processLogin(HTTPRequestPtr& http_request, TCPConnectionPtr& tcp_conn) { // strip off trailing slash if the request has one std::string resource(HTTPServer::stripTrailingSlash(http_request->getResource())); if (resource != m_login && resource != m_logout) { return false; // no login processing done } std::string redirect_url = HTTPTypes::url_decode(http_request->getQuery("url")); std::string new_cookie; bool delete_cookie = false; if (resource == m_login) { // process login // check username std::string username = HTTPTypes::url_decode(http_request->getQuery("user")); std::string password = HTTPTypes::url_decode(http_request->getQuery("pass")); // match username/password PionUserPtr user=m_user_manager->getUser(username,password); if (!user) { // authentication failed, process as in case of failed authentication... handleUnauthorized(http_request,tcp_conn); return true; } // ok we have a new user session, create a new cookie, add to cache // create random cookie std::string rand_binary; rand_binary.reserve(RANDOM_COOKIE_BYTES); for (unsigned int i=0; i<RANDOM_COOKIE_BYTES ; i++) { rand_binary += static_cast<unsigned char>(m_random_die()); } HTTPTypes::base64_encode(rand_binary, new_cookie); // add new session to cache PionDateTime time_now(boost::posix_time::second_clock::universal_time()); boost::mutex::scoped_lock cache_lock(m_cache_mutex); m_user_cache.insert(std::make_pair(new_cookie,std::make_pair(time_now,user))); } else { // process logout sequence // if auth cookie presented - clean cache out const std::string auth_cookie(http_request->getCookie(AUTH_COOKIE_NAME)); if (! auth_cookie.empty()) { boost::mutex::scoped_lock cache_lock(m_cache_mutex); PionUserCache::iterator user_cache_itr=m_user_cache.find(auth_cookie); if (user_cache_itr!=m_user_cache.end()) { m_user_cache.erase(user_cache_itr); } } // and remove cookie from browser delete_cookie = true; } // if redirect defined - send redirect if (! redirect_url.empty()) { handleRedirection(http_request,tcp_conn,redirect_url,new_cookie,delete_cookie); } else { // otherwise - OK handleOk(http_request,tcp_conn,new_cookie,delete_cookie); } // yes, we processed login/logout somehow return true; }