Merge pull request #22679 from mattwire/dummyreturn
[civicrm-core.git] / ext / authx / README.md
index 478414b320d799dd08c033c5a4b208b129f9aa97..d5404a88bfa50c059e18cd9974d1a30cb7a8c127 100644 (file)
@@ -5,7 +5,7 @@ This is useful for automated testing and developing multi-modal pageflows (eg em
 
 ## Overview
 
-There are two general flows of authentication:
+There are two general flows of authentication, each with a few variations:
 
 * __Ephemeral / Stateless__: The client submits a singlular request (such as an API call) which includes credentials. The request is authenticated and processed, but then it is abandoned.
   There are a couple flavors of stateless authentication:
@@ -15,7 +15,7 @@ There are two general flows of authentication:
     * __X-Header (`xheader`)__: The credential is again submitted with an HTTP header (`X-Civi-Auth:`). The header behaves the same as the common header. The
       differing name means that clients must specifically support it, but it also reduces the odsd of interference.
 * __Persistent / Stateful__: The client makes a request for a persistent session, attaching the contact ID and/or user ID. These will be used in subsequent requests.
-    * __End-point session (`endpoint`)__: The client submits an explicit authentication request (`POST /civicrm/authx/login?_authx=<credential>`) which creates a session and cookie.
+    * __End-point session (`login`)__: The client submits an explicit authentication request (`POST /civicrm/authx/login?_authx=<credential>`) which creates a session and cookie.
       The authenticated session endures until one logs out (`/civicrm/authx/logout`).
     * __Auto session (`auto`)__: The clients submits a GET request for any page (`?_authx=<credential>&_authxSes=1`). The session is initialized. The user redirects
       to original page.
@@ -48,8 +48,8 @@ For each authentication flow, one may toggle support for different credentials a
     * Accepted credentials (`authx_xheader_cred`): `['jwt']`
     * User link (`authx_xheader_user`): `'optional'`
 * Persistent: End-point session flow
-    * Accepted credentials (`authx_endpoint_cred`): `['jwt']`
-    * User link (`authx_endpoint_user`): `require`
+    * Accepted credentials (`authx_login_cred`): `['jwt']`
+    * User link (`authx_login_user`): `require`
 * Persistent: Auto session flow
     * Accepted credentials (`authx_auto_cred`): `['paramalogin']` for Joomla, and `[]` for all others
     * User link (`authx_auto_user`): `require`
@@ -68,30 +68,62 @@ Some modes may not be supported in some environments. For example:
 
 ### JSON Web Token
 
+By default, JSON Web Tokens are accepted for authentication in all flows.
+
+To use JWT authentication, you must first prepare a token on the server:
+
 ```php
-// First, on the server, prepare a token
-$token = Civi::service('authx.jwt')->create([
-  'contact_id' => 123,
-  'ttl' => 5*60*60,
+$token = Civi::service('crypto.jwt')->encode([
+  'exp' => time() + 5*60,       // Expires in 5 minutes
+  'sub' => 'cid:203',           // Subject (contact ID)
+  'scope' => 'authx',           // Allow general authentication
 ]);
+```
+
+This `$token` should be given to some other agent (e.g.  web browser, custom script, or email client).
+
+For example, here's a custom script which uses the `$token` to call APIv3 (`Contact.get`).  The token is based with the common HTTP authorization header:
 
-// Next, on the client, use this same token
+```php
 $options = ['http' => [
-    'method'  => 'GET',
-    'header' => 'Authorization: Bearer '.$token
+  'method'  => 'GET',
+  'header' => "Authorization: Bearer $token",
 ]];
+$url = 'https://example.org/civicrm/ajax/rest?entity=Contact&action=get&json='
+  . urlencode(json_encode(["id" => "user_contact_id"]));
 $context  = stream_context_create($options);
 $response = file_get_contents($url, false, $context);
 ```
 
-### Username and Password
+Alternatively, if you needed to send an email with a sign-in link, the JWT could be passed as an `?_authx` parameter.
 
 ```php
-$auth = base64_encode("username:password");
-$context = stream_context_create([
-    "http" => [
-        "header" => "Authorization: Basic $auth"
-    ]
-]);
-$homepage = file_get_contents("http://example.com/file", false, $context );
+$url = CRM_Utils_System::url('civicrm/dashboard', [
+  '_authx' => "Bearer $token",
+  '_authxSes' => 1,
+], TRUE, NULL, FALSE);
+$html = sprintf('<body>Here is your login link: <a href="%s">%s</a></body>',
+  htmlentities($url), htmlentities($url));
+CRM_Utils_Mail::send([...'html' => $html...]);
+```
+
+### Username and Password
+
+By default, username/password authentication is not enabled.
+
+```
+$ curl 'https://demouser:demopass@example.org/civicrm/authx/id'
+HTTP 401 Password authentication is not supported
+```
+
+However, if you activate it, then it will work with standard HTTP clients:
+
 ```
+$ cv ev 'Civi::settings()->set("authx_header_cred", ["pass","jwt"]);'
+
+$ curl 'https://demouser:demopass@example.org/civicrm/authx/id'
+{"contact_id":203,"user_id":"2"}
+```
+
+The "AuthX: Authenticate to services with password" CiviCRM permission must
+also be granted for the role associated to the user.