diff --git a/cookbooks/arcgis-enterprise/attributes/portal_authentication.rb b/cookbooks/arcgis-enterprise/attributes/portal_authentication.rb new file mode 100644 index 0000000..7dd6396 --- /dev/null +++ b/cookbooks/arcgis-enterprise/attributes/portal_authentication.rb @@ -0,0 +1,5 @@ +default['arcgis']['portal']['authentication'].tap do |portal_authentication| + portal_authentication['disable_signup'] = false + portal_authentication['configure_active_directory_users'] = false + portal_authentication['enable_single_sign_on'] = false +end \ No newline at end of file diff --git a/cookbooks/arcgis-enterprise/libraries/portal_admin_client.rb b/cookbooks/arcgis-enterprise/libraries/portal_admin_client.rb index 01acf74..f78cc84 100644 --- a/cookbooks/arcgis-enterprise/libraries/portal_admin_client.rb +++ b/cookbooks/arcgis-enterprise/libraries/portal_admin_client.rb @@ -237,6 +237,24 @@ def set_server_ssl_certificate(cert_alias) validate_response(response) end + + def set_all_ssl(https_only) + request = Net::HTTP::Post.new(URI.parse(@portal_url + + "/sharing/rest/portals/self/update").request_uri) + + request.add_field('Referer', 'referer') + + token = generate_token(@portal_url + '/sharing/generateToken') + + request.set_form_data( + 'allSSL' => https_only, + 'token' => token, + 'f' => 'json') + + response = send_request(request) + + validate_response(response) + end def content_dir token = generate_token(@portal_url + '/sharing/generateToken') @@ -371,6 +389,24 @@ def update_system_properties(system_properties) validate_response(response) end + + def get_system_properties + token = generate_token(@portal_url + '/sharing/generateToken') + + uri = URI.parse(@portal_url + '/portaladmin/system/properties') + uri.query = URI.encode_www_form('token' => token, + 'f' => 'json') + + request = Net::HTTP::Get.new(uri.request_uri) + request.add_field('Referer', 'referer') + + response = send_request(request) + + validate_response(response) + system_properties = JSON.parse(response.body) + + return system_properties + end def webadaptors_shared_key uri = URI.parse(@portal_url + '/portaladmin/system/webadaptors/config/') @@ -443,6 +479,41 @@ def edit_log_settings(log_level, log_dir, max_log_file_age) validate_response(response) end + + def get_security_configuration + token = generate_token(@portal_url + '/sharing/generateToken') + + uri = URI.parse(@portal_url + '/portaladmin/security/config') + uri.query = URI.encode_www_form('token' => token, + 'f' => 'json') + + request = Net::HTTP::Get.new(uri.request_uri) + request.add_field('Referer', 'referer') + + response = send_request(request) + + validate_response(response) + security_configuration = JSON.parse(response.body) + + return security_configuration + end + + def set_identity_store(user_store_config, group_store_config) + request = Net::HTTP::Post.new(URI.parse(@portal_url + '/portaladmin/security/config/updateIdentityStore').request_uri) + + request.add_field('Referer', 'referer') + + token = generate_token(@portal_url + '/sharing/generateToken') + + request.set_form_data('userStoreConfig' => user_store_config.to_json, + 'groupStoreConfig' => group_store_config.to_json, + 'token' => token, + 'f' => 'json') + + response = send_request(request) + + validate_response(response) + end private diff --git a/cookbooks/arcgis-enterprise/providers/portal_authentication.rb b/cookbooks/arcgis-enterprise/providers/portal_authentication.rb new file mode 100644 index 0000000..781e5bc --- /dev/null +++ b/cookbooks/arcgis-enterprise/providers/portal_authentication.rb @@ -0,0 +1,85 @@ +action :disable_signup do + portal_admin_client = ArcGIS::PortalAdminClient.new( + @new_resource.portal_url, + @new_resource.username, + @new_resource.password) + + portal_admin_client.wait_until_available + + # avoid loosing existing system properties + # => get all existing system properties and append the new one + system_properties = portal_admin_client.get_system_properties + system_properties['disableSignup'] = true + + portal_admin_client.update_system_properties(system_properties) + + # after updating the system properties, Portal get's restarted automatically + # => wait until Portal is available again before continuing + sleep(90.0) + + new_resource.updated_by_last_action(true) +end + +action :use_windows_users do + portal_admin_client = ArcGIS::PortalAdminClient.new( + @new_resource.portal_url, + @new_resource.username, + @new_resource.password) + + portal_admin_client.wait_until_available + + security_configuration = portal_admin_client.get_security_configuration + + user_store_config = { + 'type' => "WINDOWS", + 'properties' => { + 'isPasswordEncrypted' => false, + 'user' => @new_resource.active_directory_username, + 'userPassword' => @new_resource.active_directory_password + } + } + + group_store_config = security_configuration['groupStoreConfig'] + + portal_admin_client.set_identity_store(user_store_config, group_store_config) + + portal_admin_client.wait_until_available +end + +action :enable_iis_windows_authentication do + portal_wa_name = @new_resource.wa_name + execute 'Enable Windows Authentication for Portal within IIS' do + command "%systemroot%\\system32\\inetsrv\\appcmd.exe set config \"Default Web Site/#{portal_wa_name}\" -section:system.webServer/security/authentication/windowsAuthentication /enabled:\"True\" /commit:apphost" + end +end + +action :disable_iis_anonymous_authentication do + portal_wa_name = @new_resource.wa_name + execute 'Disable Anonymous Authentication for Portal within IIS' do + command "%systemroot%\\system32\\inetsrv\\appcmd.exe set config \"Default Web Site/#{portal_wa_name}\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\"False\" /commit:apphost" + end +end + +action :add_iis_ie11_compatibility_header do + portal_wa_name = @new_resource.wa_name + ruby_block 'Add IE 11 Compatibility Header' do + block do + # get Portal's current configuration within IIS + Chef::Resource::RubyBlock.send(:include, Chef::Mixin::ShellOut) + command = "%systemroot%\\system32\\inetsrv\\appcmd.exe list config \"Default Web Site/#{portal_wa_name}\" -section:system.webServer/httpProtocol" + command_out = shell_out(command) + command_out.error! + command_stdout = command_out.stdout + + # check whether the Compatibility Header is already set + if (command_stdout.include? "X-UA-Compatible") && (command_stdout.include? "IE=11") + Chef::Log.info('IE 11 Compatibility Header is already configured for Portal') + else + command = "%systemroot%\\system32\\inetsrv\\appcmd.exe set config \"Default Web Site/#{portal_wa_name}\" -section:system.webServer/httpProtocol /+customHeaders.[name='X-UA-Compatible',value='IE=11']" + command_out = shell_out(command) + command_out.error! + end + end + action :create + end +end \ No newline at end of file diff --git a/cookbooks/arcgis-enterprise/recipes/portal_authentication.rb b/cookbooks/arcgis-enterprise/recipes/portal_authentication.rb new file mode 100644 index 0000000..87b3dfc --- /dev/null +++ b/cookbooks/arcgis-enterprise/recipes/portal_authentication.rb @@ -0,0 +1,36 @@ +arcgis_enterprise_portal_authentication 'Disabling users ability to create built-in Portal accounts' do + portal_url node['arcgis']['portal']['url'] + username node['arcgis']['portal']['admin_username'] + password node['arcgis']['portal']['admin_password'] + only_if { node['arcgis']['portal']['authentication']['disable_signup'] } + action :disable_signup +end + +if node['platform'] == 'windows' + arcgis_enterprise_portal_authentication 'Configure Portal to use Active Directory for user accounts' do + portal_url node['arcgis']['portal']['url'] + username node['arcgis']['portal']['admin_username'] + password node['arcgis']['portal']['admin_password'] + active_directory_username node['arcgis']['run_as_user'] + active_directory_password node['arcgis']['run_as_password'] + only_if { node['arcgis']['portal']['authentication']['configure_active_directory_users'] } + action :use_windows_users + end + + arcgis_enterprise_portal_authentication 'Enable Windows Authentication within IIS (Single Sign-On)' do + wa_name node['arcgis']['portal']['wa_name'] + only_if { node['arcgis']['portal']['authentication']['enable_single_sign_on'] } + action :enable_iis_windows_authentication + end + + arcgis_enterprise_portal_authentication 'Disable Anonymous Authentication within IIS (Single Sign-On)' do + wa_name node['arcgis']['portal']['wa_name'] + only_if { node['arcgis']['portal']['authentication']['enable_single_sign_on'] } + action :disable_iis_anonymous_authentication + end + + arcgis_enterprise_portal_authentication 'Add IE 11 Compatibility Header to Portal config within IIS' do + wa_name node['arcgis']['portal']['wa_name'] + action :add_iis_ie11_compatibility_header + end +end \ No newline at end of file diff --git a/cookbooks/arcgis-enterprise/resources/portal_authentication.rb b/cookbooks/arcgis-enterprise/resources/portal_authentication.rb new file mode 100644 index 0000000..2692ef3 --- /dev/null +++ b/cookbooks/arcgis-enterprise/resources/portal_authentication.rb @@ -0,0 +1,33 @@ +# +# Cookbook Name:: arcgis-enterprise +# Resource:: portal_authentication +# +# Copyright 2015 Esri +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +actions :disable_signup, :use_windows_users, :disable_iis_anonymous_authentication, + :enable_iis_windows_authentication, :add_iis_ie11_compatibility_header + +attribute :portal_url, :kind_of => String +attribute :wa_name, :kind_of => String +attribute :username, :kind_of => String +attribute :password, :kind_of => String +attribute :active_directory_username, :kind_of => String +attribute :active_directory_password, :kind_of => String + +def initialize(*args) + super + @action = :install +end diff --git a/roles/webgis-windows.json b/roles/webgis-windows.json index 7afdca1..113687c 100644 --- a/roles/webgis-windows.json +++ b/roles/webgis-windows.json @@ -32,7 +32,12 @@ "setup":"C:\\ArcGIS\\10.5\\Portal\\Setup.exe", "authorization_file":"C:\\ArcGIS\\10.5\\Authorization_Files\\Portal.prvc", "keystore_file":"C:\\keystore\\mydomain_com.pfx", - "keystore_password":"changeit" + "keystore_password":"changeit", + "authentication":{ + "disable_signup":true, + "enable_single_sign_on":true, + "configure_active_directory_users":true + } } }, "run_list":[ @@ -43,6 +48,7 @@ "recipe[arcgis-enterprise::datastore]", "recipe[arcgis-enterprise::portal]", "recipe[arcgis-enterprise::portal_wa]", - "recipe[arcgis-enterprise::federation]" + "recipe[arcgis-enterprise::federation]", + "recipe[arcgis-enterprise::portal_authentication]" ] } \ No newline at end of file