This repository was archived by the owner on Jan 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 246
[ms_rest_azure] Introduce support for acquiring token from Managed Service Identity #889
Merged
Merged
Changes from 6 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
e113921
Introduce support for acquring token from Managed Service Identity
vishrutshah dc7b1aa
Update to latest azure-storage gem
vishrutshah 13b2fb2
Reusing ActiveDirectorySericeSettings for MSITokenProvider
vishrutshah 8738e1d
Testing CI from fix from Tank for azure-core gem
vishrutshah 75d4660
Using katmsft master branch
vishrutshah 90c4ef2
Using bundler version 1.14.1
vishrutshah 0205452
Remove use of private fork for azure-core
vishrutshah a5f71dc
Adding Changelog
vishrutshah File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
runtime/ms_rest_azure/lib/ms_rest_azure/credentials/msi_token_provider.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| # encoding: utf-8 | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
|
||
| module MsRestAzure | ||
| # | ||
| # Class that provides access to authentication token via Managed Service Identity. | ||
| # | ||
| class MSITokenProvider < MsRest::TokenProvider | ||
|
|
||
| private | ||
|
|
||
| TOKEN_ACQUIRE_URL = 'http://localhost:{port}/oauth2/token' | ||
| REQUEST_BODY_PATTERN = 'authority={authentication_endpoint}{tenant_id}&resource={resource_uri}' | ||
| DEFAULT_SCHEME = 'Bearer' | ||
|
|
||
| # @return [MSIActiveDirectoryServiceSettings] settings. | ||
| attr_accessor :settings | ||
|
|
||
| # @return [String] tenant id (also known as domain). | ||
| attr_accessor :tenant_id | ||
|
|
||
| # @return [Integer] port number where MSI service is running. | ||
| attr_accessor :port | ||
|
|
||
| # @return [String] auth token. | ||
| attr_accessor :token | ||
|
|
||
| # @return [Time] the date when the current token expires. | ||
| attr_accessor :token_expires_on | ||
|
|
||
| # @return [Integer] the amount of time we refresh token before it expires. | ||
| attr_reader :expiration_threshold | ||
|
|
||
| # @return [String] the type of token. | ||
| attr_reader :token_type | ||
|
|
||
| public | ||
|
|
||
| # | ||
| # Creates and initialize new instance of the MSITokenProvider class. | ||
| # @param tenant_id [String] tenant id (also known as domain). | ||
| # @param port [Integer] port number where MSI service is running. | ||
| # @param settings [ActiveDirectoryServiceSettings] active directory setting. | ||
| def initialize(tenant_id, port = 50342, settings = ActiveDirectoryServiceSettings.get_azure_settings) | ||
| fail ArgumentError, 'Tenant id cannot be nil' if tenant_id.nil? | ||
| fail ArgumentError, 'Port cannot be nil' if port.nil? | ||
| fail ArgumentError, 'Port must be an Integer' unless port.is_a? Integer | ||
| fail ArgumentError, 'Azure AD settings cannot be nil' if settings.nil? | ||
|
|
||
| @tenant_id = tenant_id | ||
| @port = port | ||
| @settings = settings | ||
|
|
||
| @expiration_threshold = 5 * 60 | ||
| end | ||
|
|
||
| # | ||
| # Returns the string value which needs to be attached | ||
| # to HTTP request header in order to be authorized. | ||
| # | ||
| # @return [String] authentication headers. | ||
| def get_authentication_header | ||
| acquire_token if token_expired | ||
| "#{token_type} #{token}" | ||
| end | ||
|
|
||
| private | ||
|
|
||
| # | ||
| # Checks whether token is about to expire. | ||
| # | ||
| # @return [Bool] True if token is about to expire, false otherwise. | ||
| def token_expired | ||
| @token.nil? || Time.now >= @token_expires_on + expiration_threshold | ||
| end | ||
|
|
||
| # | ||
| # Retrieves a new authentication token. | ||
| # | ||
| # @return [String] new authentication token. | ||
| def acquire_token | ||
| token_acquire_url = TOKEN_ACQUIRE_URL.dup | ||
| token_acquire_url['{port}'] = @port.to_s | ||
|
|
||
| url = URI.parse(token_acquire_url) | ||
|
|
||
| connection = Faraday.new(:url => url, :ssl => MsRest.ssl_options) do |builder| | ||
| builder.adapter Faraday.default_adapter | ||
| end | ||
|
|
||
| request_body = REQUEST_BODY_PATTERN.dup | ||
| request_body['{authentication_endpoint}'] = ERB::Util.url_encode(@settings.authentication_endpoint) | ||
| request_body['{tenant_id}'] = ERB::Util.url_encode(@tenant_id) | ||
| request_body['{resource_uri}'] = ERB::Util.url_encode(@settings.token_audience) | ||
|
|
||
| response = connection.post do |request| | ||
| request.headers['content-type'] = 'application/x-www-form-urlencoded' | ||
| request.body = request_body | ||
| end | ||
|
|
||
| fail AzureOperationError, | ||
| 'Couldn\'t acquire access token from Managed Service Identity, please verify your tenant id, port and settings' unless response.status == 200 | ||
|
|
||
| response_body = JSON.load(response.body) | ||
| @token = response_body['access_token'] | ||
| @token_expires_on = Time.at(Integer(response_body['expires_on'])) | ||
| @token_type = response_body['token_type'] | ||
| end | ||
| end | ||
|
|
||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # encoding: utf-8 | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
|
||
| require 'rspec' | ||
| require 'ms_rest_azure' | ||
|
|
||
| module MsRestAzure | ||
|
|
||
| describe MSITokenProvider do | ||
| it 'should throw error if nil data is passed into constructor' do | ||
| expect { MSITokenProvider.new(nil) }.to raise_error(ArgumentError) | ||
| expect { MSITokenProvider.new('tenant_id',nil) }.to raise_error(ArgumentError) | ||
| expect { MSITokenProvider.new('tenant_id','port') }.to raise_error(ArgumentError) | ||
| expect { MSITokenProvider.new('tenant_id',50431,nil) }.to raise_error(ArgumentError) | ||
| end | ||
|
|
||
| it 'should set defaults for managed service identity' do | ||
| tenant = 'xxxx-xxxx-xxxxx-xxxxx' | ||
| azure_cloud = MsRestAzure::AzureEnvironments::AzureCloud | ||
|
|
||
| token_provider = MSITokenProvider.new(tenant) | ||
| expect(token_provider.send(:tenant_id)).to eq(tenant) | ||
| expect(token_provider.send(:port)).to eq(50342) | ||
| settings = token_provider.send(:settings) | ||
| expect(settings.authentication_endpoint).to eq(azure_cloud.active_directory_endpoint_url) | ||
| expect(settings.token_audience).to eq(azure_cloud.active_directory_resource_id) | ||
| end | ||
|
|
||
| it 'should set customs for managed service identity' do | ||
| tenant = 'xxxx-xxxx-xxxxx-xxxxx' | ||
| port = 50333 | ||
| settings = ActiveDirectoryServiceSettings.new() | ||
| settings.authentication_endpoint = 'https://login.microsoftonline.com/' | ||
| settings.token_audience = 'https://vault.azure.net' | ||
|
|
||
| token_provider = MSITokenProvider.new(tenant, port, settings) | ||
| expect(token_provider.send(:tenant_id)).to eq(tenant) | ||
| expect(token_provider.send(:port)).to eq(port) | ||
| settings = token_provider.send(:settings) | ||
| expect(settings.authentication_endpoint).to eq(settings.authentication_endpoint) | ||
| expect(settings.token_audience).to eq(settings.token_audience) | ||
| end | ||
| end | ||
|
|
||
| end |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revert use of private fork after release of
azure-coreversion 0.1.11