user.auth.provider

Attributes

AUTHENTICATION_PROVIDERS

Classes

HasName

Base class for protocol classes.

Conclusion

A final answer of AuthenticationProvider().

Success

Indicates a sucessful authentication.

Failure

Indicates a corrupt JWT

InvalidJWT

Indicates a failed authentication.

ProviderMetadata

Holds provider-specific metadata.

AuthenticationProvider

Base class and registry for third party authentication providers.

SeparateAuthenticationProvider

Base class for separate authentication providers.

IntegratedAuthenticationProvider

Base class for integrated authentication providers.

RolesMapping

Takes a role mapping and provides access to it.

LDAPAttributes

Holds the LDAP server-specific attributes.

LDAPProvider

Generic LDAP Provider that includes authentication via LDAP.

LDAPKerberosProvider

Combines LDAP with Kerberos. LDAP handles authorisation, Kerberos

OauthProvider

General Prototype class for an Oath Provider with typical OAuth flow.

AzureADProvider

Authenticates and authorizes a user in AzureAD for a specific AzureAD

SAML2Provider

Authenticates and authorizes a user on SAML2 IDP

OIDCProvider

Authenticates and authorizes a user on SAML2 IDP

Functions

spawn_ldap_client(→ onegov.user.auth.clients.LDAPClient)

Takes an LDAP configuration as found in the YAML and spawns an LDAP

ensure_user(→ onegov.user.User)

Creates the given user if it doesn't already exist. Ensures the

Module Contents

class user.auth.provider.HasName[source]

Bases: Protocol

Base class for protocol classes.

Protocol classes are defined as:

class Proto(Protocol):
    def meth(self) -> int:
        ...

Such classes are primarily used with static type checkers that recognize structural subtyping (static duck-typing).

For example:

class C:
    def meth(self) -> int:
        return 0

def func(x: Proto) -> int:
    return x.meth()

func(C())  # Passes static type check

See PEP 544 for details. Protocol classes decorated with @typing.runtime_checkable act as simple-minded runtime protocols that check only the presence of given attributes, ignoring their type signatures. Protocol classes can be generic, they are defined as:

class GenProto(Protocol[T]):
    def meth(self) -> T:
        ...
property name: str[source]
user.auth.provider.AUTHENTICATION_PROVIDERS[source]
class user.auth.provider.Conclusion[source]

A final answer of AuthenticationProvider().

class user.auth.provider.Success[source]

Bases: Conclusion

Indicates a sucessful authentication.

user: onegov.user.User[source]
note: translationstring.TranslationString[source]
__bool__() Literal[True][source]
class user.auth.provider.Failure[source]

Bases: Conclusion

Indicates a corrupt JWT

note: translationstring.TranslationString[source]
__bool__() Literal[False][source]
class user.auth.provider.InvalidJWT[source]

Bases: Failure

Indicates a failed authentication.

note: translationstring.TranslationString[source]
__bool__() Literal[False][source]
class user.auth.provider.ProviderMetadata[source]

Holds provider-specific metadata.

name: str[source]
title: str[source]
class user.auth.provider.AuthenticationProvider[source]

Base class and registry for third party authentication providers.

to: str | None[source]
primary: bool[source]
name: str[source]
metadata: ClassVar[HasName][source]
classmethod __init_subclass__(metadata: HasName | None = None, **kwargs: Any)[source]
classmethod configure(name: str, **kwargs: Any) Self | None[source]
Abstractmethod:

This function gets called with the per-provider configuration defined in onegov.yml. Authentication providers may optionally access these values.

The return value is either a provider instance, or none if the provider is not available.

is_primary(app: onegov.user.UserApp) bool[source]

Returns whether the authentication provider is intended to be the primary provider for this app.

available(app: onegov.user.UserApp) bool[source]

Returns whether the authentication provider is available for the current app. Since there are tenant specific connections, we want to tcheck, if for the tenant of the app, there is an available client.

class user.auth.provider.SeparateAuthenticationProvider[source]

Bases: AuthenticationProvider

Base class for separate authentication providers.

Seperate providers render a button which the user can click to do a completely separate request/response handling that eventually should lead to an authenticated user.

kind: ClassVar[Literal['separate']] = 'separate'[source]
abstract authenticate_request(request: onegov.core.request.CoreRequest) Success | Failure | webob.Response | None[source]

Authenticates the given request in one or many steps.

Providers are expected to return one of the following values:

  • A conclusion (if the authentication was either successful or failed)

  • None (if the authentication failed)

  • A webob response (to perform handshakes)

This function is called whenever the authentication is initiated by the user. If the provider returns a webob response, it is returned as is by the calling view.

Therefore, authenticate_request must take care to return responses in a way that eventually end up fulfilling the authentication. At the very least, providers should ensure that all parameters of the original request are kept when asking external services to call back.

abstract button_text(request: onegov.core.request.CoreRequest) str[source]

Returns the translatable button text for the given request.

It is okay to return a static text, if the button remains the same for all requests.

The translatable text is parsed as markdown, to add weight to the central element of the text. For example:

Login with **Windows**
class user.auth.provider.IntegratedAuthenticationProvider[source]

Bases: AuthenticationProvider

Base class for integrated authentication providers.

Integrated providers use the username/password entered in the normal login form and perform authentication that way (with fallback to the default login mechanism).

kind: ClassVar[Literal['integrated']] = 'integrated'[source]
abstract hint(request: onegov.core.request.CoreRequest) str[source]

Returns the translatable hint shown above the login mask for the integrated provider.

It is okay to return a static text, if the hint remains the same for all requests.

The translatable text is parsed as markdown.

abstract authenticate_user(request: onegov.core.request.CoreRequest, username: str, password: str) User | None[source]

Authenticates the given username/password in a single step.

The function is expected to return an existing user record or None.

user.auth.provider.spawn_ldap_client(ldap_url: str | None = None, ldap_username: str | None = None, ldap_password: str | None = None, **cfg: Any) onegov.user.auth.clients.LDAPClient[source]

Takes an LDAP configuration as found in the YAML and spawns an LDAP client that is connected. If the connection fails, an exception is raised.

user.auth.provider.ensure_user(source: str | None, source_id: str | None, session: sqlalchemy.orm.Session, username: str, role: str, force_role: bool = True, realname: str | None = None, force_active: bool = False) onegov.user.User[source]

Creates the given user if it doesn’t already exist. Ensures the role is set to the given role in all cases.

class user.auth.provider.RolesMapping[source]

Takes a role mapping and provides access to it.

A role mapping maps a onegov-cloud role to an LDAP role. For example:

admins -> ACC_OneGovCloud_User

The mapping comes in multiple levels. For example:

  • “__default__” Fallback for all applications

  • “onegov_org” Namespace specific config

  • “onegov_org/govikon” Application specific config

Each level contains a group name for admins, editors and members. See onegov.yml.example for an illustrated example.

roles: dict[str, dict[str, str]][source]
app_specific(app: HasApplicationIdAndNamespace) dict[str, str] | None[source]
match(roles: Mapping[str, str], groups: Collection[str]) str | None[source]

Takes a role mapping (the fallback, namespace, or app specific one) and matches it against the given LDAP groups.

Returns the matched group or None.

class user.auth.provider.LDAPAttributes[source]

Holds the LDAP server-specific attributes.

name: str[source]
mails: str[source]
groups: str[source]
password: str[source]
uid: str[source]
classmethod from_cfg(cfg: dict[str, Any]) Self[source]
class user.auth.provider.LDAPProvider[source]

Bases: IntegratedAuthenticationProvider

Generic LDAP Provider that includes authentication via LDAP.

ldap: onegov.user.auth.clients.LDAPClient[source]
auth_method: str[source]
attributes: LDAPAttributes[source]
roles: RolesMapping[source]
custom_hint: str = ''[source]
classmethod configure(name: str, **cfg: Any) Self | None[source]

This function gets called with the per-provider configuration defined in onegov.yml. Authentication providers may optionally access these values.

The return value is either a provider instance, or none if the provider is not available.

hint(request: onegov.core.request.CoreRequest) str[source]

Returns the translatable hint shown above the login mask for the integrated provider.

It is okay to return a static text, if the hint remains the same for all requests.

The translatable text is parsed as markdown.

authenticate_user(request: onegov.core.request.CoreRequest, username: str, password: str) User | None[source]

Authenticates the given username/password in a single step.

The function is expected to return an existing user record or None.

authenticate_using_compare(request: onegov.core.request.CoreRequest, username: str, password: str) User | None[source]
class user.auth.provider.LDAPKerberosProvider[source]

Bases: SeparateAuthenticationProvider

Combines LDAP with Kerberos. LDAP handles authorisation, Kerberos handles authentication.

ldap: onegov.user.auth.clients.LDAPClient[source]
kerberos: onegov.user.auth.clients.KerberosClient[source]
attributes: LDAPAttributes[source]
roles: RolesMapping[source]
suffix: str | None = None[source]
classmethod configure(name: str, **cfg: Any) Self | None[source]

This function gets called with the per-provider configuration defined in onegov.yml. Authentication providers may optionally access these values.

The return value is either a provider instance, or none if the provider is not available.

button_text(request: onegov.core.request.CoreRequest) str[source]

Returns the request tailored to each OS (users won’t understand LDAP/Kerberos, but for them it’s basically their local OS login).

authenticate_request(request: onegov.core.request.CoreRequest) webob.Response | Success | Failure[source]

Authenticates the given request in one or many steps.

Providers are expected to return one of the following values:

  • A conclusion (if the authentication was either successful or failed)

  • None (if the authentication failed)

  • A webob response (to perform handshakes)

This function is called whenever the authentication is initiated by the user. If the provider returns a webob response, it is returned as is by the calling view.

Therefore, authenticate_request must take care to return responses in a way that eventually end up fulfilling the authentication. At the very least, providers should ensure that all parameters of the original request are kept when asking external services to call back.

request_authorization(request: onegov.core.request.CoreRequest, username: str) User | None[source]
class user.auth.provider.OauthProvider[source]

Bases: SeparateAuthenticationProvider

General Prototype class for an Oath Provider with typical OAuth flow.

abstract do_logout(request: onegov.core.request.CoreRequest, user: onegov.user.User, to: str) webob.Response | None[source]

May return a webob response that gets used instead of the default logout response, to perform e.g. a redirect to the external provider.

If no special response is necessary because the external logout is skipped/unecessary or performed through a back-channel, this will just return None and fall through to the default logout response which will terminate the local user session.

abstract request_authorisation(request: onegov.core.request.CoreRequest) Success | Failure | webob.Response[source]

Takes the request from the redirect_uri view sent from the users browser. The redirect view expects either: * a Conclusion, either Success or Failure * a webob response, e.g. to redirect to the logout page

The redirect view, where this function is used, will eventually fulfill the login process whereas self.authenticate_request() is purely to redirect the user to the auth provider.

logout_redirect_uri(request: onegov.core.request.CoreRequest) str[source]

This url usually has to be registered with the OAuth Provider. Should not contain any query parameters.

redirect_uri(request: onegov.core.request.CoreRequest) str[source]

Returns the redirect uri in a consistent manner without query parameters.

class user.auth.provider.AzureADProvider[source]

Bases: OauthProvider

Authenticates and authorizes a user in AzureAD for a specific AzureAD tenant_id and client_id in an OpenID Connect flow.

For this to work, we need

  • Client ID

  • Client Secret

  • Tenant ID

We have to give the AzureAD manager following Urls, that should not change:

  • Redirect uri (https://<host>/auth_providers/msal/redirect)

  • Logout Redirect uri (https://<host>/auth/logout)

Additionally, weh AzureAD Manager should set additional token claims for the authorisation to work:

  • email claim

  • groups claim for role mapping

  • optional: family_name and given_name for User.realname

The claims preferred_username or upn could also be used for User.realname.

tenants: onegov.user.auth.clients.msal.MSALConnections[source]
roles: RolesMapping[source]
custom_hint: str = ''[source]
classmethod configure(name: str, **cfg: Any) Self | None[source]

This function gets called with the per-provider configuration defined in onegov.yml. Authentication providers may optionally access these values.

The return value is either a provider instance, or none if the provider is not available.

button_text(request: onegov.core.request.CoreRequest) str[source]

Returns the translatable button text for the given request.

It is okay to return a static text, if the button remains the same for all requests.

The translatable text is parsed as markdown, to add weight to the central element of the text. For example:

Login with **Windows**
do_logout(request: onegov.core.request.CoreRequest, user: onegov.user.User, to: str) None[source]

May return a webob response that gets used instead of the default logout response, to perform e.g. a redirect to the external provider.

If no special response is necessary because the external logout is skipped/unecessary or performed through a back-channel, this will just return None and fall through to the default logout response which will terminate the local user session.

logout_url(request: onegov.core.request.CoreRequest) str[source]
authenticate_request(request: onegov.core.request.CoreRequest) webob.Response | Failure[source]

Returns a redirect response or a Conclusion

Parameters of the original request are kept for when external services call back.

validate_id_token(request: onegov.core.request.CoreRequest, token: dict[str, Any]) Failure | Literal[True][source]

Makes sure the id token is validated correctly according to https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation

request_authorisation(request: onegov.core.request.CoreRequest) Success | Failure[source]

If “Stay Logged In” on the Microsoft Login page is chosen, AzureAD behaves like an auto-login provider, redirecting the user back immediately to the redirect view without prompting a password or even showing any Microsoft page. Microsoft set their own cookies to make this possible.

Return a webob Response or a Conclusion.

is_primary(app: onegov.user.UserApp) bool[source]

Returns whether the authentication provider is intended to be the primary provider for this app.

available(app: onegov.user.UserApp) bool[source]

Returns whether the authentication provider is available for the current app. Since there are tenant specific connections, we want to tcheck, if for the tenant of the app, there is an available client.

class user.auth.provider.SAML2Provider[source]

Bases: OauthProvider

Authenticates and authorizes a user on SAML2 IDP

tenants: onegov.user.auth.clients.saml2.SAML2Connections[source]
roles: RolesMapping[source]
custom_hint: str = ''[source]
classmethod configure(name: str, **cfg: Any) Self | None[source]

This function gets called with the per-provider configuration defined in onegov.yml. Authentication providers may optionally access these values.

The return value is either a provider instance, or none if the provider is not available.

button_text(request: onegov.core.request.CoreRequest) str[source]

Returns the translatable button text for the given request.

It is okay to return a static text, if the button remains the same for all requests.

The translatable text is parsed as markdown, to add weight to the central element of the text. For example:

Login with **Windows**
do_logout(request: onegov.core.request.CoreRequest, user: onegov.user.User, to: str) webob.Response | None[source]

May return a webob response that gets used instead of the default logout response, to perform e.g. a redirect to the external provider.

If no special response is necessary because the external logout is skipped/unecessary or performed through a back-channel, this will just return None and fall through to the default logout response which will terminate the local user session.

authenticate_request(request: onegov.core.request.CoreRequest) webob.Response | Failure[source]

Returns a redirect response or a Conclusion

Parameters of the original request are kept for when external services call back.

request_authorisation(request: onegov.core.request.CoreRequest) Success | Failure[source]

Returns a webob Response or a Conclusion.

is_primary(app: onegov.user.UserApp) bool[source]

Returns whether the authentication provider is intended to be the primary provider for this app.

available(app: onegov.user.UserApp) bool[source]

Returns whether the authentication provider is available for the current app. Since there are tenant specific connections, we want to tcheck, if for the tenant of the app, there is an available client.

class user.auth.provider.OIDCProvider[source]

Bases: OauthProvider

Authenticates and authorizes a user on SAML2 IDP

tenants: onegov.user.auth.clients.oidc.OIDCConnections[source]
roles: RolesMapping[source]
custom_hint: str = ''[source]
classmethod configure(name: str, **cfg: Any) Self | None[source]

This function gets called with the per-provider configuration defined in onegov.yml. Authentication providers may optionally access these values.

The return value is either a provider instance, or none if the provider is not available.

button_text(request: onegov.core.request.CoreRequest) str[source]

Returns the translatable button text for the given request.

It is okay to return a static text, if the button remains the same for all requests.

The translatable text is parsed as markdown, to add weight to the central element of the text. For example:

Login with **Windows**
do_logout(request: onegov.core.request.CoreRequest, user: onegov.user.User, to: str) webob.Response | None[source]

May return a webob response that gets used instead of the default logout response, to perform e.g. a redirect to the external provider.

If no special response is necessary because the external logout is skipped/unecessary or performed through a back-channel, this will just return None and fall through to the default logout response which will terminate the local user session.

authenticate_request(request: onegov.core.request.CoreRequest) webob.Response | Failure[source]

Returns a redirect response or a Conclusion

Parameters of the original request are kept for when external services call back.

request_authorisation(request: onegov.core.request.CoreRequest) Success | Failure[source]

Returns a webob Response or a Conclusion.

is_primary(app: onegov.user.UserApp) bool[source]

Returns whether the authentication provider is intended to be the primary provider for this app.

available(app: onegov.user.UserApp) bool[source]

Returns whether the authentication provider is available for the current app. Since there are tenant specific connections, we want to tcheck, if for the tenant of the app, there is an available client.