0.01
No release in over 3 years
Low commit activity in last 3 years
Easy way for Ruby applications to authenticate to Azure B2C/AD in order to access protected web resources.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

 Project Readme

AzureJwtAuth

Build Status

Easy way for Ruby applications to authenticate to Azure B2C/AD in order to access protected web resources.

Installation

Add this line to your application's Gemfile:

gem 'azure_jwt_auth'

And then execute:

$ bundle

Or install it yourself as:

$ gem install azure_jwt_auth

Usage with Rails

First of all, we add our providers into an initializer:

# config/initializers/azure.rb

require 'azure_jwt_auth/jwt_manager'

AzureJwtAuth::JwtManager.load_provider(
  :b2c,
  'https://login.microsoftonline.com/.../v2.0/.well-known/openid-configuration')
)

AzureJwtAuth::JwtManager.load_provider(
  :ad,
  'https://sts.windows.net/.../v2.0/.well-known/openid-configuration'
)
...

Then, we add Authenticable module into ApplicationController and define entity_from_token_payload method.
This method is used by Authenticable module to load current_user.

require 'azure_jwt_auth/authenticable'

class ApplicationController < ActionController::API
  include AzureJwtAuth::Authenticable

  rescue_from AzureJwtAuth::NotAuthorized, with: :render_401

  private

  def render_401
    render json: {}, status: 401
  end

  def entity_from_token_payload(payload)
    # Returns a valid entity, `nil` or raise
    # e.g.
    #   User.find payload['sub']
  end
end

Finally, we can use authenticate! method into ours controllers:

class ExampleController < ApplicationController
  before_action :authenticate!

  ...
end

Providers

Provider class initializer receives the following parameters:

parameter description
uid unique provider identifier
config_url azure url to get config
validations payload fields validations which will be checked for each token: {payload_field: value_expected, ...} (optional)

We create providers using the AzureJwtAuth::JwtManager.load_provider method:

AzureJwtAuth::JwtManager.load_provider(
  :b2c, # uid
  'https://login.microsoftonline.com/.../v2.0/.well-known/openid-configuration'), # config_url
  {'aud' => 'my_app_id'} # validations
)

Authenticable

This module provides us with the following methods:

  • authenticate!

    Check if a token is valid for any provider and loads current_user. Otherwise it throws an exception.

    If you need other behavior you can define your custom authenticate! method like this:

    def my_authenticate!
      begin
        token = JwtManager.new(request, :privider_id)
        unauthorize! unless token.valid?
      rescue
        unauthorize!
      end
    
      @current_user = User.find(token.payload['sub'])
    end
  • current_user

    Returns current_user loaded by authenticate! method.

  • signed_in?

    Check if exists current_user.

  • unauthorize!

    Throws a AzureJwtAuth::NotAuthorized exception.

Testing (rspec)

Require the AzureJwtAuth::Spec::Helpers helper module in rails_helper.rb.

  require 'azure_jwt_auth/spec/helpers'
  ...
  RSpec.configure do |config|
    ...
    config.include AzureJwtAuth::Spec::Helpers, :type => :controller
  end

And then we can just call sign_in(user):

  describe ExampleController
    let(:user) { MyEntity.create(...) }

    it "blocks unauthenticated access" do
      get :index
      expect(response).to have_http_status(401)
    end

    it "allows authenticated access" do
      sign_in user # user will be returned by current_user method
      get :index
      expect(response).to have_http_status(200)
    end
  end

License

The gem is available as open source under the terms of the MIT License.