You can apply this method. We refuse cookies in general, but in each request we send a security token: hash(<пароль>+<URL страницы>+<текущая дата-время с точностью до минуты>)
. For example, http://example.com/some/page?security=12345678
. It is clear that the server can verify the correctness of the token, since it knows the password. And the attacker cannot compose this token, since he does not know the password, and by intercepting an HTTP request, he will recognize the token for only one page, which is valid for a minute.
Of course, we do not want to force the user to calculate and drive a hash into the address bar. We can either create an absolutely dynamic Javascript website, which asks for a password at the beginning of the session, and then loads all pages with Ajax, secretly adding tokens to URLs. Or you can store the password in the local storage of the browser (LocalStorage), and add Javascript to each page, which rules all links after loading - then we can make a less dynamic website with real page reloads.
It is clear that this is all trash, but, as I understand it, you have a problem with some local site, for example, an enterprise site. In this case, the transformation of the site into a web application can probably be justified. If the site is public, then these perversions will not go unnoticed, and users will not love you for them.
The given scheme is quite safe, but only if we have read-only man-in-the-middle. But if he can edit the information transmitted from the server to the client, then everything is bad - he will simply replace his home page, which will not store the password locally, but send it directly to him. And nothing can be done with this, except for what has already been done in SSL, namely, server identification with the help of a certificate. Well, it is impossible to find out if the server is correct, whether the authorization page is correct (whether the salt was sent by the server, etc.), without agreeing with it about some general secret that can be checked, revealing this secret, or not agreeing with someone else, who agreed with the server. A secret that can be verified without opening it means using public key cryptography. A third party contract is the use of a third-party certification server whose certificate is preinstalled on the client system. These two things, by and large, make up the SSL protocol, so the best thing you can do is overcome your certain problem that prevents you from using SSL.