Birds-Eye.Net
All things broadband and more...
 
Web Birds-Eye.Net

What's New?

Ruby on Rails (RoR)
Programming Reference


Models
External database connections
Passing current_user into model
Passing object into model
Using static lookup tables
Validates IF
Validates MongoMapper

Views
Dynamically delete form element
Edit create nested data
HTML form field check_box
Layout jQuery datatable module
Select array
Select cascading via JS
Text_area Array
Text_area listing submit
Text field format time

Controllers
Dynamic model selection
Including first item from a sorted desc table
Using from_unixtime on epoch dates
Custom SQL Query Examples

Rack
Integrated NTLM/Kerberos Authentication
Pass-through Authentication w/ NTLM

ActionMailer
Broken links in emails

Rails General
Add, Subtract, Multiply, and Divide
Calculate number of weekdays for date range
Date->Epoch & Epoch->Date
Calculate past/present payroll dates
Extract first letter of each word
Hash of hashes assignment
Using: variable as hash index

jQuery
jQuery accordion MongoDB

Rails Framework Examples

Apotomo Widget Using Erb

MySQL
Converting Julian Dates to Epoch

d3 Charting
Configuration to Work with Rails Apps
A simple bar chart example

Other
Setup VPN on iMac
SSH Key Generation

More to come

 

Using Rack for Windows Pass Through Authentication with NTLM

By: Bruce Bahlmann - Contributing Author (your feedback is important to us!)

In rails development, particularly when operating over an enterprise or Citrix network where all your end user browsers end up being some standard version of Microsoft Internet Explorer (IE), a logical way to authenticate clients is to hijack their previous authentication onto the IT network. In other circles this hijacking would be referred to as windows pass-through authentication as what you are doing is bypassing individual application authentication and instead using the authentication the end user already completed as a result of logging into the IT network.

If you are a Microsoft Windows shop with a surplus of IIS web servers, you basically get this authentication for free as these windows-based web servers return a convenient REMOTE_USER environmental variable which is essentially the user's current login name. From there, a simple look up in Active Directory (AD) via the sAMAccountName gives you all the information you need about that login name - without the user having to log in or provide you anything. Well, if you are reading this, clearly you DO NOT HAVE such an IIS setup, but are wanting to obtain the REMOTE_USER variable with some other web server like Apache, nGenx, etc. In this article, we show you a web server independent way to generate REMOTE_USER. Start by including one key resources Net/NTLM to your Gemfile.

[Gemfile]
gem 'rubyntlm'

Next you need to add some Rack library code to allow your Rails application to handle the NTLM rather than require your web server to do this. The essential library is below, but you could just as easily expand on this to include AD lookups, etc. so as to provide more details about the user - like their first/last name, email, etc.
[lib/auth_ntlm.rb]
require 'net/ntlm'
require 'kconv'

class AuthNtlm
  def initialize(app, config = {})
    @app = app
    @options = {}
    @config = {
      ## Initialize Defaults
      :uri_pattern => /\//
    }.merge(config)
  end

  def call(env)
    @status,@headers,@response = @app.call(env)
    if env['PATH_INFO'] =~ @config[:uri_pattern] && env['HTTP_AUTHORIZATION'].blank?
      return [401, {'WWW-Authenticate' => "NTLM"}, []]
    end

    if /^(NTLM|Negotiate) (.+)/ =~ env["HTTP_AUTHORIZATION"]
      message = Net::NTLM::Message.decode64($2)

      if message.type == 1
        type2 = Net::NTLM::Message::Type2.new
          return [401, {"WWW-Authenticate" => "NTLM " + type2.encode64}, []]
        end
      end

      if message.type == 3 && env['PATH_INFO'] =~ @config[:uri_pattern]
        user = Net::NTLM::decode_utf16le(message.user)
        @headers['REMOTE_USER'] = user
      end
    else
      #return [200, {"Content-Type" => "text/html"}, ["not sure what to do here..." + env.inspect]]
    end
    [@status,@headers,self]
  end

  def each(&block)
    @response.each(&block)
  end
end

One serious limitation about NTLM is that although it works great for obtaining the login name of users which clearly could be used to look up those users on a network, NTLM does not provide access to the user's login password. While it is true that NTLM does a hash of the user password, this hash is of the user password converted to all CAPS and appears to be a one-way hash to boot. So, even if you were able to figure out how to un-hash/translate the NTLM password from its traces used by NTLM, you will not have a usable password once that is complete because the process would be insensitive to the password case.

The final step in activating the Rack is to insert the call into the application configuration.

[config/application.rb]
  class Application < Rails::Application
…

   config.middleware.use "AuthNtlm", {
      :uri_pattern => /\//                       # (default = /\//) (any URL)
    }

    # Custom directories with classes and modules you want to be autoloadable.
    #config.autoload_paths += %W(#{config.root}/extras)
    config.autoload_paths += %W(#{config.root}/lib)

The call to your Rack library file should be placed below the class Application < Rails::Application line within module named after your Rails application. Note, there is one other change, that is to tell Rails to autoload your Rack library files placed in /lib. To do this, you need to uncomment and modify or add a new similar line (what we did) to configure the autoload. If you do not tell Rails to autoload, Rails will not know where to find your Rack application.

We would like to acknowledge the previous contribution of lukefx who originally authored rack-ntlm from which our work was based. We could not make rack-ntlm work as it is presented in GitHub, there is also the serious limitation about passwords which lukefx conveniently failed to mention, instead he hard coded the users password into the application configuration.

If you need to support lots of different browsers (particularly FireFox), this solution will not work. Your best bet in this case would be to use rack-auth-kerberos. However, if you are an IE shop, the above solution should work just fine.

Can Birds-Eye.Net help you or your Company?
Receive your Birds-Eye.Net articles and white papers hot off the presses by adding our RSS feed to your reader.

 

(C) Copyright Birds-Eye.Net, All rights reserved.
It is against the law to reproduce this content or any portion of it in any form without the explicit written permission of Birds-Eye Network Services, LLC. Federal copyright law (17 USC 504) makes it illegal, punishable with fines up to $100,000 per violation plus attorney's fees.