Package: ckanext-passwordless_api
CKAN Passwordless APIExtension to allow paswordless login to the CKAN API.Documentation:https://envidat.gitlab-pages.wsl.ch/ckanext-passwordless_api/Source Code:https://gitlabext.wsl.ch/EnviDat/ckanext-passwordless_apiThis plugin is primarily intended for custom frontends built on the CKAN API.By using API tokens from CKAN core (>2.9), this plugin provides an authentication flow where:Users receive a login token via email (via reset key in core).API token is returned on valid login token (reset key) submission.The API token should then be included in Authorization headers from the frontend --> CKAN calls.Based on work by @espona (Lucia Espona Pernas) for ckanext-passwordless (https://github.com/EnviDat/ckanext-passwordless).A second login flow is also supported, using Azure AD:User logs in with authorization code flow in frontend (@azure/msal-browser or similar).Azure token is passed to azure specific endpoint.Token is validated and API token for CKAN is returned.The API token should then be included in Authorization headers from the frontend --> CKAN calls.Installpipinstallckanext-passwordless-apiConfigOptional variables can be set in your ckan.ini:passwordless_api.guidelines_urlDescription: A link to your website guidelines.Default: None, not included.passwordless_api.policies_urlDescription: A link to your website policies.Default: None, not included.passwordless_api.welcome_templateDescription: Path to welcome template to render as html email.Default: uses default template.passwordless_api.reset_key_templateDescription: Path to reset key template to render as html emailDefault: uses default template.passwordless_api.cookie_nameDescription: Set to place the API token in a cookie, with given name.
The cookie will default tosecure,httpOnly,samesite: Lax.Default: None, no cookie used.passwordless_api.cookie_domainDescription: The domain for samesite to respect, required if cookie set.Default: None.passwordless_api.cookie_samesiteDescription: To change the cookie samesite value toStrict.
Only enable this if you know what you are doing.Default: None, samesite value is set toLax.passwordless_api.cookie_http_onlyDescription: Use a httpOnly cookie, recommended.Default: true.passwordless_api.cookie_pathDescription: Set a specific path to use the cookie, e.g./api.Default:/(all paths).passwordless_api.anonymous_usernamesDescription: Set to true to anonymise usernames when generated.Default: false.passwordless_api.anonymous_domain_exceptionsDescription: Email domain exceptions that should not be anonymised, if enabled.Default: None.EndpointsPOST<CKAN_HOST>/api/3/action/passwordless_request_reset_keyDescription: Request a login token for a given email.Creates user if they do not exist & sends welcome email.Param1: email (str).<CKAN_HOST>/api/3/action/passwordless_request_api_tokenDescription: Request an API token, given the email and login token (reset_key).Param1: email (str).Param2: key (str).<CKAN_HOST>/api/3/action/passwordless_request_api_token_azure_adDescription: Request an API token, given the email and Azure AD token.Param1: email (str).Param2: token (str).<CKAN_HOST>/api/3/action/passwordless_revoke_api_tokenDescription: Revoke an API token.Param1: token (str).GET<CKAN_HOST>/api/3/action/passwordless_revoke_api_tokenDescription: If logged in, revoke the current API token.<CKAN_HOST>/api/3/action/passwordless_get_userDescription: Get user details, given their API token.Also resets and returns a new API token (i.e. renewal).Fails silently if the user is not logged in.Use the coreuser_showaction if refresh is not required.<CKAN_HOST>/api/3/action/passwordless_introspectDescription: Verify if the API token is valid for a user.This does not renew the token in the same call.Mostly useful for auth checking in microservice APIs.Using the cookie in an Authorization headerIf configured, the cookie containing an API token can't do much on it's own.It is possible to extract the cookie value using frontend JS and pass to the CKAN backend, but this makes your site vulnerable to XSS attacks.Instead the cookie should be stored in a secure way:samesite=Laxwithdomain=YOUR_DOMAINto help prevent CSRF.samesite=Strictis even more secure, but significantly impacts UX for your site.secureto help prevent man-in-the-middle.httpOnlyto help prevent XSS.Setting this means the cookie can no longer be accessed from your JS code.Then a middleware must be used to convert the cookie value into a header than CKAN can interpret:NGINX server example(nginx is the default/recommended server to reverse proxy CKAN)
(https://docs.ckan.org/en/latest/maintaining/installing/deployment.html)# Add the cookie-based API token to the request Authorization header# This is passed to the CKAN backend & read automatically by CKANproxy_set_header'Authorization'$cookie_${AUTH_COOKIE_NAME};# If using caching omit the cookieproxy_cache_bypass$cookie_${AUTH_COOKIE_NAME};proxy_no_cache$cookie_${AUTH_COOKIE_NAME};Apache server exampleSetEnvIfCookie"(^|;\ *)${AUTH_COOKIE_NAME}=([^;\ ]+)"ckan_cookie_value=$2RequestHeadersetAuthorization"%{ckan_cookie_value}e"NotesIt is also recommended to disable access to the API via cookie, to help prevent CSRF:ckan.auth.disable_cookie_auth_in_api = trueThe configuration for API tokens can be configured in core:api_token.nbytes=60api_token.jwt.decode.secret=string:YOUR_SUPER_SECRET_STRINGapi_token.jwt.algorithm=HS256# expire_api_token plugin (unit = 1 day in seconds, lifetime = 3 days)expire_api_token.default_lifetime=3expire_api_token.default_unit=86400