Package: jhub-authenticators
An extended collection of HTTP(S) header JupyterHub Authenticators that relies on proxy authenticating.
Every mentioned authenticator should be used while following
the mentioned security recommendations atcwaldbieser.InstallationInstallation from pypi:pip install jhub-authenticatorsInstallation from local git repository:cd jhub-authenticators
pip install .Dummy AuthenticationProvides an option for testing JupyterHub authentication with a dummy authenticator
that can have a global preset password for any account:c.JupyterHub.authenticator_class = 'jhubauthenticators.DummyAuthenticator'
c.DummyAuthenticator.password = 'password'Note! Don’t use in production.Header AuthenticationThis Header Authentication method provides multiple functionalities beyond mere authentication. It can activated by adding the following to the JupyterHub configuration:c.JupyterHub.authenticator_class = 'jhubauthenticators.HeaderAuthenticator'By default, it exposes the following paths:'/login' -> is utilizied to authenticate the user, relies on the 'allowed_headers' parameter to accomplish this.
'/logout' -> clears the users authenticated session.
'/set-user-data' -> allows an authenticated user to provide data to be persisted during the authenticated session. Here the 'user_external_allow_attributes' parameter defines which user attributes are allowed to be set.Specify Authentication HeaderFirst it provides the possibility to define a custom authentication header,
this is accomplished by overriding the default allowed_headers dict requiredauthkey:c.HeaderAuthenticator.allowed_headers = {'auth': 'MyAuthHeader'}This will overrive the defaultRemote-Userheader authentication to use theMyAuthHeaderinstead.Additional User Data HeadersBeyond theauthkey, the administrator is allowed to set additional headers that the authenticator will accept requests on.For instance, if theMyCustomHeadershould be accepted as well during authentication:c.HeaderAuthenticator.enable_auth_state = True
c.HeaderAuthenticator.allowed_headers = {'auth': 'MyAuthHeader',
                                         'auth_data': 'MyCustomHeader'}Any information provided via theMyCustomHeaderduring authentication will be added to the JupyterHub user’sauth_state,
dictionary as defined byAuthenticators auth_state. The data will be added to theauth_stateby utilizing the header value in theallowed_headersdictionary as the key in the ‘auth_state’ dictionary. For instance the above configuration, will produce the following user profile:user = {
    name: 'stored MyAuthHeader value',
    'auth_state': {'MyCustomHeader': 'stored MyCustomHeader value'}
}It’s important to note here, that this information is only persisted for the life-time of the authenticated session.Sharing auth_state data with Spawner EnvironementIf any of the definedauth_statekey-value pairs should be set as Spawner environement variables before a notebook is spawned, thespawner_shared_headersparameter is available to define this, E.g if the “MyCustomHeader’ should do this, it can be accomplished with the following addition to the configuration:c.HeaderAuthenticator.spawner_shared_headers = ['MyCustomHeader']Which duringpre_spawn_hookwill produce the following environment variable:~>env | grep MyCustomHeader

MyCustomHeader="stored MyCustomHeader value"Special ParsersIf the administrator requires that the definedallowed_headersshould be parsed in a special way.
The administrator can use theheader_parser_classesparameter to define how a request with a particular header should be parsed, E.g:from jhubauthenticators import Parser, JSONParser

c.HeaderAuthenticator.header_parser_classes = {'auth': Parser,
                                               'auth_data': JSONParser}Theauthheader is here set to be parsed by the default Parser, which just returns the provided value unchanged.
The JSONParser, however does what it indicated, attempts to parse the data as JSON.In addition to these, the authenticator also provides theRegexUsernameParserwhich can be used as anauthparser, E.g:# RegexUsernameParser
c.HeaderAuthenticator.header_parser_classes = {'auth': RegexUsernameParser}
# Email regex
RegexUsernameParser.username_extract_regex = '([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)'Which will try to expand an email from the definedauthallowed_headers Header. If this can’t be accomplished, the user will not be authenticated.Related to theusername_extract_regex, theRegexUsernameParser.replace_extract_charsparameter exists to accomplish post filtering of illegal characters on the extracted username, E.g:# Replace every '@' and '.' char in the extracted username with '_'
RegexUsernameParser.replace_extract_chars = {'@': '_', '.': '_'}It is possible to define additional parsers by extending the Parser class and implementing the required parse method, E.g:class MyParser(Parser)

    # MyAdvancedParser
    def parse(self, data)
        return dataWhich can subsequently be activate by adding it to theheader_parser_classesparameter, E.g.:# MyAdvancedParser
c.HeaderAuthenticator.header_parser_classes = {'auth': MyParser}Set User state after AuthenticationFinally, the HeaderAuthenticator also provides the administrator the possibility to define theuser_external_allow_attributesparameter.
This allows defines which user attributes an authenticated user is allowed to set a user-defined variable via the HeaderAuthenticator defined/set-user-dataendpoint.
For instance, an authentiacated user’s variabledatacould be allowed to be externally defined by defining the following configuration:c.HeaderAuthenticator.user_external_allow_attributes = ['data']By default theuser_external_allow_attributesallows no such attributes and has to be explicitly enabled/defined.
Furthermore, this will only allow an authenticated user to externally define their owndatainstance variable.Additional configuration examples of this can be found in thetests/jupyterhub_configsdirectory.