This repository has been archived by the owner on Feb 6, 2024. It is now read-only.
External authenticator implementation (Issue #32) #98
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I have implemented external authenticator support for CASino based on the description you provided on Issue 32:
My needs were specifically for Facebook authentication using their JavaScript SDK. I have created a Facebook authenticator to work with this external authentication implementation, which you can view here.
Configuration:
I have added a new section to the
cas.yml
file which mimics the existing authenticator section.An example of this:
Implementation:
The external authenticators were designed with the expectation that each will provide a view and a validation function.
External authenticator base class:
View:
The view function provides the path to the view, used for rendering the button on the login page.
An example of this taken from my casino_facebook-authenticator:
Because the view is embedded in the external authenticator itself, it is expected that the external authenticators will be implemented as minimal Rails Engines.
Validation
Unlike the current validation function that relies on a username and password, I have made the external authenticator's validation function require request parameters and cookies. I figured this would provide the most flexibility while still providing the necessary data to support most authentication services.
As an example, my Facebook authenticator expects the access token to be generated on the client side and then passed via POST parameters to the server for server side verification. The assumption is that other external authenticators would use a similar client side approach for generating the necessary authentication tokens or cookies required.
Processor Concern - Authentication
In order to support this new validation functionality, I had to make changes to the app/processors/casino/processor_concern/authentication.rb.
There are now two different validation functions:
You'll notice that the
validate_external_credentials
only validates for the authenticator that was submitted via theexternal
parameter.The common functionality has been placed in the
validate
function:Because there are now two different types of authenticators, I had to also change the
authenticators
method signature to take an authenticator type. The cached@authenticators
has also been changed to be a hash, which is keyed on authenticator type.Login Credential Acceptor Processor
The trigger that is used to know when to invoke an external authenticator or a regular authenticator happens based on whether the external parameter is submitted. This check happens in the /login_credential_acceptor_processor.rb.
Login Page
The external authenticator buttons are rendered on the login page within an inline list. Each view is wrapped in its own form, containing the login ticket and external hidden inputs.
The idea being that each authenticator will submit the wrapping form when necessary, including any additional data that may be needed on the server side.
As an example, my Facebook authenticator submits the form via JavaScript after the Facebook login process has completed and the access token has been added to the form dynamically as a hidden input.
External Authenticator List
Because the view needs to render a view for each of the authenticators, I pass a list of external authenticators to the view via the
@external_authenticators
. This list is passed from the processor, to the listener and then to the view. This is not ideal, as it does introduce some repetitiveness in the processor, but I needed to be able to reuse the processor_concern/authentication.rb'sauthenticators
method, and therefore keeping this call in the processor made sense.Example (login_credential_requestor_processor.rb):
Please let me know if you have any questions, concerns or changes. I look forward to hearing your input.
Thank you.