Skip to content

Commit

Permalink
First pass
Browse files Browse the repository at this point in the history
  • Loading branch information
marknadig committed May 30, 2014
1 parent 47c4997 commit ca7d409
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in omniauth-azure-oauth2.gemspec
gemspec

group :example do
gem 'sinatra'
end
81 changes: 81 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# OmniAuth Windows Azure Active Directory Strategy WAAD

This gem provides a simple way to authenticate to Windows Azure Active Directory (WAAD) over OAuth2 using OmniAuth.

One of the unique challenges of WAAD OAuth is that WAAD is multi tenant. Any given tenant can have multiple active
directories. The CLIENT-ID, REPLY-URL and keys will be unique to the tenant/AD/application combination. This gem simply
provides hooks for determining those unique values for each call.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'omniauth-azure-auth2'
```

## Usage

First, you will need to add your site as an application in WAAD.:
[Adding, Updating, and Removing an Application](http://msdn.microsoft.com/en-us/library/azure/dn132599.aspx)

Summary:
Select your Active Directory in https://manage.windowsazure.com/<tenantid> of type 'Web Application'. Name, sign-on url,
logo are not important. You will need the CLIENT-ID from the application configuration and you will need to generate
an expiring key (aka 'client secret'). REPLY URL is the oauth redirect uri.
The APP ID UI just needs to be unique and identify your site and isn't needed to configure the gem.
Permissions need Delegated Permissions to at least have "Enable sign-on and read user's profiles".
Note: Seems like the terminology is still fluid, so follow the MS guidance (buwahaha) to set this up.

```ruby
use OmniAuth::Builder do
provider :azure, YourTentProvider
end
```

The TenantProvider class must provide client_id, client_secret and tenant_id. For a simple single-tenant app, this could be:

```ruby
class YouTenantProvider
def self.client_id
ENV['AZURE_CLIENT_ID']
end

def self.client_secret
ENV['AZURE_CLIENT_SECRET']
end

def self.tenant_id
ENV['AZURE_TENANT_ID']
end
end
```

## Auth Hash Schema

The following information is provided back to you for this provider:

```ruby
{
uid: '12345',
info: {
name: 'some one', # may be email
first_name: 'some',
last_name: 'one',
email: '[email protected]'
},
credentials: {
token: 'thetoken', # can be used to auth to the API
refresh_token: 'refresh' # can be used refresh the token
},
extra: { raw_info: raw_api_response }
}
```

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes and tests (`git commit -am 'Added some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
6 changes: 6 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require File.join('bundler', 'gem_tasks')
require File.join('rspec', 'core', 'rake_task')

RSpec::Core::RakeTask.new(:spec)

task :default => :spec
31 changes: 31 additions & 0 deletions examples/sinatra.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
$:.push File.dirname(__FILE__) + '/../lib'

require 'omniauth-azure-oauth2'
require 'sinatra'

class MyAzureProvider
def self.client_id
ENV['AZURE_CLIENT_ID']
end

def self.client_secret
ENV['AZURE_CLIENT_SECRET']
end

def self.tenant_id
ENV['AZURE_TENANT_ID']
end

end

use Rack::Session::Cookie
use OmniAuth::Strategies::Azure, MyAzureProvider

get '/' do
"<a href='/auth/azure_oauth2'>Log in with Azure</a>"
end

get '/auth/azure_oauth2/callback' do
content_type 'text/plain'
request.env['omniauth.auth'].inspect
end
1 change: 1 addition & 0 deletions lib/omniauth-azure-oauth2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require File.join('omniauth', 'azure_oauth2')
1 change: 1 addition & 0 deletions lib/omniauth/azure_oauth2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require File.join('omniauth', 'strategies', 'azure_oauth2')
5 changes: 5 additions & 0 deletions lib/omniauth/azure_oauth2/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module OmniAuth
module AzureOauth2
VERSION = "0.0.1"
end
end
53 changes: 53 additions & 0 deletions lib/omniauth/strategies/azure_oauth2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
require 'omniauth/strategies/oauth2'
require 'jwt'

module OmniAuth
module Strategies
class AzureOauth2 < OmniAuth::Strategies::OAuth2
BASE_AZURE_URL = 'https://login.windows.net'

option :name, 'azure_oauth2'

option :tenant_provider, nil

# AD resource identifier
option :resource, '00000002-0000-0000-c000-000000000000'

# tenant_provider must return client_id, client_secret, tenant_id
args [:tenant_provider]

def client
# Fold on options from dynamic tenant provider
options.client_id = options.tenant_provider.client_id
options.client_secret = options.tenant_provider.client_secret
options.tenant_id = options.tenant_provider.tenant_id

options.client_options.authorize_url = "#{BASE_AZURE_URL}/#{options.tenant_id}/oauth2/authorize"
options.client_options.token_url = "#{BASE_AZURE_URL}/#{options.tenant_id}/oauth2/token"

options.token_params.resource = options.resource
super
end

uid {
raw_info['sub']
}

info do
{
name: raw_info['unique_name'],
first_name: raw_info['given_name'],
last_name: raw_info['family_name'],
email: raw_info['email'] || raw_info['upn']
}
end


def raw_info
# it's all here in JWT http://msdn.microsoft.com/en-us/library/azure/dn195587.aspx
@raw_info ||= JWT.decode(access_token.token, nil, false)
end

end
end
end
26 changes: 26 additions & 0 deletions omniauth-azure-oauth2.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# -*- encoding: utf-8 -*-
require File.expand_path(File.join('..', 'lib', 'omniauth', 'azure_oauth2', 'version'), __FILE__)

Gem::Specification.new do |gem|
gem.authors = ["Mark Nadig"]
gem.email = ["[email protected]"]
gem.description = %q{An Windows Azure Active Directory OAuth2 strategy for OmniAuth}
gem.summary = %q{An Windows Azure Active Directory OAuth2 strategy for OmniAuth}
gem.homepage = "https://github.com/KonaTeam/stragetgies"

gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
gem.files = `git ls-files`.split("\n")
gem.test_files = `git ls-files -- {spec}/*`.split("\n")
gem.name = "omniauth-azure-oauth2"
gem.require_paths = ["lib"]
gem.version = OmniAuth::AzureOauth2::VERSION
gem.license = "MIT"

gem.add_dependency 'omniauth', '~> 1.0'
gem.add_dependency 'jwt', '~> 0.1'

gem.add_runtime_dependency 'omniauth-oauth2', '~> 1.1'

gem.add_development_dependency 'rspec', '>= 2.14.0'
gem.add_development_dependency 'rake'
end
6 changes: 6 additions & 0 deletions spec/omniauth/strategies/azure_oauth2_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require 'spec_helper'
require 'omniauth-azure-oauth2'

describe OmniAuth::Strategies::AzureOauth2 do

end
2 changes: 2 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require File.join('bundler', 'setup')
require 'rspec'

0 comments on commit ca7d409

Please sign in to comment.