- Issue created by @cmlara
- π¦πΊAustralia mingsong π¦πΊ
In case anyone interested how to make TFA working with REST API at this stage, I would suggest following login process instead your custom REST API login form/page.
- Redirect your custom login URL to the Drupal login URL(/user/login) or Drupal login form.
- Inject your business logic into the Drupal login form via Drupal form alert hook function. Such as redirecting the user to a API landing page by the following codes.
// URL string. $form_state->setRedirect('route', $args, $options); // Or a Drupal URL object. $form_state->setRedirectUrl($url);
Once the user has signed in with TFA, then the browser will remember the user session via cookies. After this point, the user will be able to access any API or non-API pages as long as the user has the permission to do so.
- π¦πΊAustralia mingsong π¦πΊ
Is the TFA Web Services sub module created for this purpose?
The /Drupal/services_tfa/Plugin/ServiceDefinition::processRequest() function looks like a solution for it, right?
https://git.drupalcode.org/project/tfa/-/blob/2.x/services_tfa/src/Plugi...
- πΊπΈUnited States cmlara
Is the TFA Web Services sub module created for this purpose?
To be honest I question if tfa_services was every fully designed and implemented. It appears to have been brought in during Week 7 of the 2016 GSOC with the description of "Add Web Serivces To TFA, Add the missing reset form class". I assume this was a result of a direct conversation with the GSOC mentor as I've been unable to find anything related to it otherwise.
See: https://github.com/d8-contrib-modules/tfa/pull/57
See: https://github.com/therealssj/GSoC2016-Final-ReportA key point is at the moment it only validates a token is valid and provides an answer to the client without using the token to validate or control authentication.
I've pushed up some code that I was originally working on the 1.x branch in parallel to working on on SA-CONTIRB-2023-030. I've rebased onto the 2.x branch but not tested it on 2.x It is very much a work in progress and shouldn't have an MR opened yet as I recall it had some edge cases that I needed to clean up, though I can't remember what they were at the moment. It also absolutely needed tests written.
The main design of the code is that it intercepts the user.authentication.cookie service, ensuring that authenticate() only approves sessions that have provided a token, otherwise they cant receive 'authentication' status. In theory by being at the authentication provider we actually should be able to lock down security going forward, issues like π User login via route user.login.http bypasses TFA Closed: outdated in theory wouldn't be possible for session based authentication anywhere, as if any route provides session authentication it wouldn't get approval from the TFA cookie service.
I'll note that this only covers SESSION based authentication, we would have to discuss how to handle other methods such as basic_auth and other random authentication (may require that we maintain a whitelist and de-register unknown method, or make it very clear that TFA is not protecting those methods.)
There are other methods for session as well, instead of using the tfa_services module we could extend/replace the existing user.login.http route and either use the 'password+token" method, there are multiple formats or we could add our own field onto the existing route and decode it for the token.
This part is really more a "whats the cleanest api"
β¨ Increase security with single failure for login, password, and tfa Postponed: needs info comes into play as well regarding design on if we choose to use 'multiple requests' or 'single request'. I'm honestly more partial to single request as that prevents knowing if the password or the token was invalid.
- πΊπΈUnited States cmlara
Opened π Decorate the user.auth service Fixed as another possible solution. Discussing in its own issue as it touches on a few more areas than just the REST, however it would allow us to protect known password based authentications without significant overhauls and without interfering with other formats such as API access keys that are not password based.
A user would authenticate using the ldap/radius style format for the password where the password field becomes a combination of password and token. There are several styles of this such as:
$password . $token $password . '+' . $token // '+' may be any character or even multiple characters in theory) // The above two but reversed order. $token . $password $token . '+' . $password
- πΊπΈUnited States cmlara
Looking at π Decorate the user.auth service Fixed I believe that is a cleaner method of implementing the authentication validation for REST than what I have submitted into this issue so far.
I would suggest we adopt π Decorate the user.auth service Fixed and just use this issue to determine if we want to make any additional changes to REST API, such as adding explicit fields or routes. We may also want to remove tfa_services if it provides no actual security features.
- π΅πΉPortugal jcnventura
And in a related path, we should deprecate and remove the tfa_services module: π Deprecate the services_tfa module Active
- Status changed to Closed: outdated
11 months ago 12:48am 5 January 2024 - πΊπΈUnited States cmlara
This was solved by π Decorate the user.auth service Fixed .