How to validate LTI requests with Warden Strategy

Tram Ho

Original article How to Validate LTI Requests with a Custom Warden Strategy

Have you ever found some way to validate incoming requests based on a specific condition in a Rails application?

Probably many of you have not learned in depth about Warden but this article will give a little more knowledge on how to validate incoming requests with warden.

Imagine some use cases for multiple authorization strategies with cases that need to handle authentication for some other API endpoints or need to handle authentication based on The params provided or changed the authentication mechanism based on the application’s environment.

When there are new requirements, all incoming requests for specific environments can only follow LTI standards. The rest of the environments still use the authentication information with the password authentication flow, for example, so it’s not a substitute for everything. Instead it needs to be supported by 2 flow of side-by-side authentication temporarily calling Warden Strategies enter stage right

Overview of Warden Strategies

For us, learning about Warden Strategies is probably not of much value. Next to Warden, what is it?

Warden is a gem that can be used in Ruby Rack-based applications to open the authentication system in the app middleware. Warden provides session processing and uses a rack object to set authentication information (including user objects).

A Warden Strategy contains logic for authentication requests. Multilayer tactics can be used in an application. Warden will run through all tactics until successful, failed or found no match for a specific request. A warden strategy usually contains at least 2 methods:

  • valid? ( optional method ) checks whether the tactics match and produces true or false results. If true the tactics will be run otherwise false will not run. Run by default without this function.
  • authenticate! ( required method ) enforces authentication logic. You can pause the stack strategy or forward the next strategy (default forwarding when halt! not called)

All tactics have request-related methods and action methods inheriting from Warden::Strategies::Base that can be used in tactics. The method may call to suspend the stack strategy or login a user if authentication is successful. See the example below

Optional LTI Warden Strategy

Now that we have a rough idea of ​​Warden Strategies, next we will go to the tactical option to validate LTI requests. First, LTI is a protocol that allows learning tools (applications) to ensure secure communication between them. An LTI request is just a POST request with predefined params including an OAuth signature, shared key and other OAuth / request information. For specific cases, only LTI requests will be filtered. So the authentication strategy for requests can be the first and only tactics. Tactics will be added and guaranteed to be checked first in the stack:

The code below will add tactics and want to ensure that only specific environments are run:

Should we use the #valid? method #valid? in it only when LtiAuth.on? is true new tactics run otherwise not run.

If in an environment in which the strategy is needed, the next method #authenticate! will be called and here is the executable logic. As mentioned above the LTI request parameters include an OAuth signature. Because Warden provides access to request methods, it is possible to pass request information to LtiAuth::RackOauthVerifier to validate the authenticity of the signature (combining the encryption of the request method, url, params, a shared key and secret). Make sure to provide sufficient user credentials. If LTI signature is valid and user param exists, the user will have the terms.

This is all there is to it, but how do you prevent subsequent tactics from executing and how to log in?

As above Warden provides action methdo halt! That method will be blocking. The above code uses #success! and #custom! activate mehtdo #halt! . If validate is successful, mehtod #success! Receive authenticated user object and set session and user information in warden rack object.

If authentication fails #custom! will receive a custom rake array and send this array as a response to the request but cannot continue into the application. To learn more about #fail!, #redirect!, và #pass , see the Warden Wiki .

It’s about request authentication and logged in user. Done? not yet.

With a set of session Warden will ignore all the tactics according to the next request. However, what if I want to verify that the session user is the appropriate user and the OAuth signature is still valid? The answer is #after_set_user

Warden provides an additional object, warden_object , which provides a #after_set_user method #after_set_user will be called every time the user is set or when a user set according to the available session data of subsequent requests.

LtiAuth::WardenAfterSetUSer class will help validate the user and provide the signature.

If both are correct, they will be run normally, in case the user is not valid or the signature is not valid user will be logged out. The logout user will run the tactical stack again.

Below are diagrams to help better understand flow authentication.

The user sends a request with a valid signature and user params. The request enters the Warden strategy and the login credentials are authenticated, setting the user. After setting the active user and all checks for the user information passed, allow the request to go to the controller.

User sent a request with invalid signature or no / invalid params. The request went to the Warden strategy and the validate failed. The error response will be sent back to the client without going to the application.

User sends subsequent requests. The request ignores the Warden strategy and a user is set based on the available session data. After activating the set user, when the OAuth signature is authenticated and requires the same user and session user, the request is successful and the application arrives.

User sends subsequent requests. The request ignores the Warden strategy and a user is set based on the available session data. After activating the set user, when the OAuth signature is invalid, that user will logout the session. After the logout Warden strategy will activate and fail because the signature is invalid and finally returns 403.

User sends subsequent requests. The request ignores the Warden strategy and a user is set based on the available session data. After activating the set user, when the OAuth signature is valid but the session user and requires another user, the session user logout. After the Warden Strategy logout is activated, the signature is valid and requires the user to set a new user, upon successful Warden Strategy After Set User and go to the application.

Thank you for reading this article!


Share the news now

Source : Viblo