Skip to content
This repository has been archived by the owner on Jan 25, 2022. It is now read-only.

Commit

Permalink
CFID-397-Fetch the public key from the cloud controller
Browse files Browse the repository at this point in the history
The public key will later be used to validate the token once the
UAA switches to using public keys for token signing

Change-Id: I092422aefd8e8361a1add0dad7fbab020205e149
  • Loading branch information
joeldsa committed Aug 21, 2012
1 parent d431907 commit 4b7062a
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 23 deletions.
2 changes: 1 addition & 1 deletion cloud_controller/Gemfile
Expand Up @@ -9,7 +9,7 @@ gem 'nats', :require => 'nats/client'
gem 'vcap_common', :require => ['vcap/common', 'vcap/component'], :git => 'https://github.com/cloudfoundry/vcap-common.git', :ref => 'fd6b6d91'
gem 'vcap_logging', :require => ['vcap/logging'], :git => 'https://github.com/cloudfoundry/common.git', :ref => 'e36886a1'
gem 'vcap_staging', '~> 0.1.62', :git => 'https://github.com/cloudfoundry/vcap-staging.git', :ref => '8d9da6cd'
gem 'cf-uaa-client', '~> 1.0', :git => 'https://github.com/cloudfoundry/uaa.git', :ref => 'b19eb89b'
gem 'cf-uaa-client', '~> 1.0', :git => 'https://github.com/cloudfoundry/uaa.git', :ref => 'dad29c90'

# For queuing staging tasks
gem 'em-hiredis'
Expand Down
15 changes: 7 additions & 8 deletions cloud_controller/Gemfile.lock
Expand Up @@ -24,17 +24,16 @@ GIT

GIT
remote: https://github.com/cloudfoundry/uaa.git
revision: b19eb89b16a7646b6272556060e52ad09fc6707d
ref: b19eb89b
revision: dad29c9030f482c7a426c9c81b0e05d9715ccc11
ref: dad29c90
specs:
cf-uaa-client (1.0.2)
em-http-request (>= 1.0.0.beta.3, <= 1.0.0.beta.3)
cf-uaa-client (1.1.1)
em-http-request
eventmachine
interact
json_pure
highline
launchy
rest-client
thor
yajl-ruby

GIT
remote: https://github.com/cloudfoundry/vcap-common.git
Expand Down Expand Up @@ -120,11 +119,11 @@ GEM
eventmachine
erubis (2.6.6)
abstract (>= 1.0.0)
highline (1.6.13)
hiredis (0.3.2)
http_parser.rb (0.5.1)
httpclient (2.2.7)
i18n (0.5.0)
interact (0.4.3)
json (1.7.3)
json_pure (1.7.3)
launchy (2.0.3)
Expand Down
28 changes: 25 additions & 3 deletions cloud_controller/app/models/uaa_token.rb
@@ -1,5 +1,6 @@
require "uaa/token_coder"
require "uaa/token_issuer"
require "uaa/misc"

class UaaToken

Expand All @@ -14,8 +15,13 @@ class UaaToken
"vmc",
nil)

@token_key_fetch_failure_count = 3


class << self

attr_accessor :token_key_fetch_failure_count

def is_uaa_token?(token)
token.nil? || /\s+/.match(token.strip()).nil?? false : true
end
Expand All @@ -25,9 +31,27 @@ def decode_token(auth_token)
return nil
end

CloudController.logger.debug("uaa token coder #{@uaa_token_coder.inspect}")
CloudController.logger.debug("Auth token is #{auth_token.inspect}")

# Try to fetch the token key (public key) from the UAA
if token_key_fetch_failure_count > 0 && !@token_key
begin
CF::UAA::Misc.async=true
@token_key ||= CF::UAA::Misc.validation_key(AppConfig[:uaa][:url], AppConfig[:uaa][:resource_id], AppConfig[:uaa][:client_secret])

if @token_key[:alg] == "SHA256withRSA"
CloudController.logger.debug("token key fetched from the uaa #{@token_key.inspect}")
@uaa_token_coder = CF::UAA::TokenCoder.new(AppConfig[:uaa][:resource_id],
AppConfig[:uaa][:token_secret],
@token_key[:value])
end
rescue => e
self.token_key_fetch_failure_count = token_key_fetch_failure_count - 1
CloudController.logger.warn("Failed to fetch the token key from the UAA token_key endpoint or recieved symmetric key instead")
CloudController.logger.debug("Request to uaa/token_key OR public key init failed. #{@token_key_fetch_failure_count} retries remain. #{e.message}")
end
end

token_information = nil
begin
token_information = @uaa_token_coder.decode(auth_token)
Expand All @@ -52,7 +76,6 @@ def access_token
if @access_token.nil? || expired?(@access_token)
#Get a new one
@token_issuer.async = true
@token_issuer.debug = true
@token_issuer.logger = CloudController.logger
@access_token = @token_issuer.client_credentials_grant().auth_header
end
Expand All @@ -62,7 +85,6 @@ def access_token

def id_token(email, password)
@id_token_issuer.async = true
@id_token_issuer.debug = true
@id_token_issuer.logger = CloudController.logger
id_token = @id_token_issuer.implicit_grant_with_creds(username: email, password: password).auth_header
CloudController.logger.debug("id_token #{id_token}")
Expand Down
9 changes: 9 additions & 0 deletions cloud_controller/spec/controllers/users_controller_spec.rb
Expand Up @@ -188,4 +188,13 @@ def post_with_body(*args, &blk)
it_should_behave_like "any request to the users controller"
end

context "using jwt tokens with RSA keys" do
before :all do
CloudSpecHelpers.use_jwt_token_with_rsa_key = true
end

it_should_behave_like "any request to the users controller"
end


end
9 changes: 9 additions & 0 deletions cloud_controller/spec/requests/app_create_spec.rb
Expand Up @@ -30,4 +30,13 @@
it_should_behave_like "any request to create a new app"
end

context "using jwt tokens with RSA keys" do
before :all do
CloudSpecHelpers.use_jwt_token_with_rsa_key = true
end

it_should_behave_like "any request to create a new app"
end


end
9 changes: 9 additions & 0 deletions cloud_controller/spec/requests/bulk_spec.rb
Expand Up @@ -178,6 +178,15 @@
it_should_behave_like "any request to the bulk api"
end

context "using jwt tokens with RSA keys" do
before :all do
CloudSpecHelpers.use_jwt_token_with_rsa_key = true
end

it_should_behave_like "any request to the bulk api"
end


def get_users(args=nil)
get(bulk_users_url, args, @auth_header)
end
Expand Down
9 changes: 9 additions & 0 deletions cloud_controller/spec/requests/info_spec.rb
Expand Up @@ -68,6 +68,15 @@
it_should_behave_like "any request"
end

context "using jwt tokens with RSA keys" do
before :all do
CloudSpecHelpers.use_jwt_token_with_rsa_key = true
end

it_should_behave_like "any request"
end



end

9 changes: 9 additions & 0 deletions cloud_controller/spec/requests/proxy_user_spec.rb
Expand Up @@ -42,4 +42,13 @@
it_should_behave_like "any request to test a proxy user"
end

context "using jwt tokens with RSA keys" do
before :all do
CloudSpecHelpers.use_jwt_token_with_rsa_key = true
end

it_should_behave_like "any request to test a proxy user"
end


end
8 changes: 8 additions & 0 deletions cloud_controller/spec/requests/user_tokens_spec.rb
Expand Up @@ -34,6 +34,14 @@
it_should_behave_like "any request for a new user token"
end

context "using jwt tokens with RSA keys" do
before :all do
CloudSpecHelpers.use_jwt_token_with_rsa_key = true
end

it_should_behave_like "any request for a new user token"
end

context "When user_expire is specified" do
before { UserToken.token_expire = 1.day }
let :token do
Expand Down
50 changes: 49 additions & 1 deletion cloud_controller/spec/support/cloud_spec_helpers.rb
@@ -1,3 +1,5 @@
require 'mocha'

module CloudSpecHelpers
# Define test scenarios for https enforcement code
HTTPS_ENFORCEMENT_SCENARIOS = [{:protocol => "http", :appconfig_enabled => [], :user => "user", :success => true},
Expand All @@ -18,6 +20,7 @@ module CloudSpecHelpers
{:protocol => "https", :appconfig_enabled => [:https_required_for_admins], :user => "admin", :success => true}]

@@use_jwt_token = false
@@use_jwt_token_with_rsa_key = false

def self.use_jwt_token
@@use_jwt_token
Expand All @@ -27,6 +30,14 @@ def self.use_jwt_token=(use_jwt_token)
@@use_jwt_token = use_jwt_token
end

def self.use_jwt_token_with_rsa_key
@@use_jwt_token_with_rsa_key
end

def self.use_jwt_token_with_rsa_key=(use_jwt_token_with_rsa_key)
@@use_jwt_token_with_rsa_key = use_jwt_token_with_rsa_key
end

# Generate a handy header Hash.
# At minimum it requires a User or email as the first argument.
# Optionally, you can pass a second User or email which will be the 'proxy user'.
Expand All @@ -36,7 +47,18 @@ def headers_for(user, proxy_user = nil, raw_data = nil, https = false)
headers = {}
if user
email = User === user ? user.email : user.to_s
if @@use_jwt_token
if @@use_jwt_token_with_rsa_key
UaaToken.stubs(:token_key_fetch_failure_count).returns(3)
CF::UAA::Misc.stubs(:validation_key).returns(public_key_from_uaa())
token_body = {"resource_ids" => ["cloud_controller"], "foo" => "bar", "email" => email}
token_coder = CF::UAA::TokenCoder.new(AppConfig[:uaa][:resource_id],
AppConfig[:uaa][:token_secret],
private_key())

token = token_coder.encode(token_body, 'RS256')
AppConfig[:uaa][:enabled] = true
headers['HTTP_AUTHORIZATION'] = "bearer #{token}"
elsif @@use_jwt_token
token_body = {"resource_ids" => ["cloud_controller"], "foo" => "bar", "email" => email}
token_coder = CF::UAA::TokenCoder.new(AppConfig[:uaa][:resource_id],
AppConfig[:uaa][:token_secret])
Expand Down Expand Up @@ -85,4 +107,30 @@ def build_admin_and_user
def random_name(length = 7)
Digest::SHA1.hexdigest("#{Time.now.nsec}-#{rand(1_000_000)}").slice(0,length)
end

def private_key
"-----BEGIN RSA PRIVATE KEY-----
MIIBywIBAAJhAOTeb4AZ+NwOtPh+ynIgGqa6UWNVe6JyJi+loPmPZdpHtzoqubnC
wEs6JSiSZ3rButEAw8ymgLV6iBY02hdjsl3h5Z0NWaxx8dzMZfXe4EpfB04ISoqq
hZCxchvuSDP4eQIDAQABAmEAqUuYsuuDWFRQrZgsbGsvC7G6zn3HLIy/jnM4NiJK
t0JhWNeN9skGsR7bqb1Sak2uWqW8ZqnqgAC32gxFRYHTavJEk6LTaHWovwDEhPqc
Zs+vXd6tZojJQ35chR/slUEBAjEA/sAd1oFLWb6PHkaz7r2NllwUBTvXL4VcMWTS
pN+5cU41i9fsZcHw6yZEl+ZCicDxAjEA5f3R+Bj42htNI7eylebew1+sUnFv1xT8
jlzxSzwVkoZo+vef7OD6OcFLeInAHzAJAjEAs6izolK+3ETa1CRSwz0lPHQlnmdM
Y/QuR5tuPt6U/saEVuJpkn4LNRtg5qt6I4JRAjAgFRYTG7irBB/wmZFp47izXEc3
gOdvA1hvq3tlWU5REDrYt24xpviA0fvrJpwMPbECMAKDKdiDi6Q4/iBkkzNMefA8
7HX27b9LR33don/1u/yvzMUo+lrRdKAFJ+9GPE9XFA==
-----END RSA PRIVATE KEY-----"
end

def public_key_from_uaa
{:alg => 'SHA256withRSA',
:value => "-----BEGIN RSA PUBLIC KEY-----
MGgCYQDk3m+AGfjcDrT4fspyIBqmulFjVXuiciYvpaD5j2XaR7c6Krm5wsBLOiUo
kmd6wbrRAMPMpoC1eogWNNoXY7Jd4eWdDVmscfHczGX13uBKXwdOCEqKqoWQsXIb
7kgz+HkCAwEAAQ==
-----END RSA PUBLIC KEY-----"}
end


end
2 changes: 1 addition & 1 deletion health_manager/Gemfile
Expand Up @@ -12,7 +12,7 @@ gem 'yajl-ruby', :require => ['yajl', 'yajl/json_gem']

gem 'vcap_common', '>= 1.0.10', :git => 'https://github.com/cloudfoundry/vcap-common.git', :ref => 'cbeb8a17'
gem "vcap_logging", "~> 1.0.0", :git => 'https://github.com/cloudfoundry/common.git', :ref => 'e36886a1'
gem 'cf-uaa-client', '~> 1.0', :git => 'https://github.com/cloudfoundry/uaa.git', :ref => 'b19eb89b'
gem 'cf-uaa-client', '~> 1.0', :git => 'https://github.com/cloudfoundry/uaa.git', :ref => 'dad29c90'

group :test do
gem "rspec"
Expand Down
16 changes: 7 additions & 9 deletions health_manager/Gemfile.lock
Expand Up @@ -15,17 +15,16 @@ GIT

GIT
remote: https://github.com/cloudfoundry/uaa.git
revision: b19eb89b16a7646b6272556060e52ad09fc6707d
ref: b19eb89b
revision: dad29c9030f482c7a426c9c81b0e05d9715ccc11
ref: dad29c90
specs:
cf-uaa-client (1.0.2)
em-http-request (>= 1.0.0.beta.3, <= 1.0.0.beta.3)
cf-uaa-client (1.1.1)
em-http-request
eventmachine
interact
json_pure
highline
launchy
rest-client
thor
yajl-ruby

GIT
remote: https://github.com/cloudfoundry/vcap-common.git
Expand Down Expand Up @@ -55,8 +54,8 @@ GEM
http_parser.rb (>= 0.5.1)
em-socksify (0.1.0)
eventmachine
highline (1.6.13)
http_parser.rb (0.5.3)
interact (0.4.3)
json_pure (1.7.3)
launchy (2.1.0)
addressable (~> 2.2.6)
Expand Down Expand Up @@ -84,7 +83,6 @@ GEM
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
thor (0.15.3)
yajl-ruby (0.8.3)

PLATFORMS
Expand Down

0 comments on commit 4b7062a

Please sign in to comment.