Reputation: 2723
I added digest authentication to my CherryPy server, and I wanted to know on what criteria the users' authentication is revoked and they are prompted to enter credentials again. Deleting cookies doesn't force a prompt, but using Incognito or another browser does.
My config:
{ 'tools.auth_digest.on': True,
'tools.auth_digest.realm': 'localhost',
'tools.auth_digest.get_ha1': auth_digest.get_ha1_dict_plain(USERS),
'tools.auth_digest.key': key,
'tools.auth_digest.accept_charset': 'UTF-8' }
Thanks
Upvotes: 1
Views: 324
Reputation: 5741
You need to have the proper HTTP response so that the browser clear out the user credentials, basically responding with 401 Unauthorized
and a challenge in how to authenticate with the WWW-Authenticate
header.
Here is an implementation using a custom CherryPy tool and a Cookie
that is used as way to communicate the intention to the browser and the backend (HTTP auth is stateless and we have to go back and forth to deauth and redirect).
import cherrypy
from cherrypy.lib import auth_digest
REALM = 'localhost'
KEY = '24684651368351320asd1wdasd'
CHARSET = 'UTF-8'
@cherrypy.tools.register('before_handler')
def with_logout_handler():
if cherrypy.request.cookie.get('Unauthorize') is not None:
response = cherrypy.response
response.headers['WWW-Authenticate'] = auth_digest.www_authenticate(
realm=REALM,
key=KEY,
accept_charset=CHARSET
)
# delete the cookie that was used to mark the intention to logout
response.cookie['Unauthorize'] = 1
response.cookie['Unauthorize']['expires'] = 0
raise cherrypy.HTTPError(
401, 'You are not authorized to access that resource')
class App:
@cherrypy.expose
@cherrypy.tools.with_logout_handler()
def index(self):
return ('Welcome {}! Do you want to <a href="/logout">logout</a>?'
.format(cherrypy.request.login))
@cherrypy.expose
def logout(self):
"""
Set a cookie to give it a clue to the index method to
remove the user credentials from the following requests.
This will be handled by the tool `with_logout_handler`.
"""
cherrypy.response.cookie['Unauthorize'] = 1
raise cherrypy.HTTPRedirect("/")
def main():
users = {
'foo': 'bar'
}
cherrypy.quickstart(App(), config={
'/': {
'tools.auth_digest.on': True,
'tools.auth_digest.realm': REALM,
'tools.auth_digest.get_ha1': auth_digest.get_ha1_dict_plain(users),
'tools.auth_digest.key': KEY,
'tools.auth_digest.accept_charset': CHARSET
},
})
if __name__ == '__main__':
main()
Upvotes: 2