Skip to content

(CAT-2303): Enhance FormsAuthentication handling for IIS applications #405

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions lib/puppet/provider/iis_application/webadministration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ def sslflags=(value)
def authenticationinfo=(value)
# Using property flush to find just the changed values, for speed
@property_flush[:authenticationinfo] = value.select do |k, v|
authenticationinfo.key?(k) && authenticationinfo[k] != v
auth_info = authenticationinfo.is_a?(Hash) ? authenticationinfo : @resource[:authenticationinfo]
auth_info.key?(k) && auth_info[k] != v
end
end

Expand Down Expand Up @@ -90,9 +91,20 @@ def update
"-Filter 'system.webserver/security/access' -Name 'sslFlags' -Value '#{flags}' -ErrorAction Stop"
end

@property_flush[:authenticationinfo]&.each do |auth, _enable|
inst_cmd << "Set-WebConfigurationProperty -Location '#{self.class.find_sitename(resource)}/#{app_name}' " \
"-Filter 'system.webserver/security/authentication/#{auth}Authentication' -Name enabled -Value #{@property_flush[:authenticationinfo][auth]} -ErrorAction Stop"
@property_flush[:authenticationinfo]&.each do |auth, enable|
if auth == 'forms'
# Handle formsAuthentication separately
mode_value = enable ? 'Forms' : 'None'
# For Forms authentication, we need to set the mode value in the system.web section, not the system.webserver section
# This is a workaround for the fact that the WebAdministration module does not support setting the mode value for Forms authentication
# at the site level
inst_cmd << "Set-WebConfigurationProperty -PSPath 'IIS:/Sites/#{self.class.find_sitename(resource)}/#{app_name}' " \
"-Filter 'system.web/authentication' -Name 'mode' -Value '#{mode_value}' -ErrorAction Stop"
else
# Handle other authentication types
inst_cmd << "Set-WebConfigurationProperty -Location '#{self.class.find_sitename(resource)}/#{app_name}' " \
"-Filter 'system.webserver/security/authentication/#{auth}Authentication' -Name enabled -Value #{enable} -ErrorAction Stop"
end
end

if @property_flush[:enabledprotocols]
Expand Down
28 changes: 22 additions & 6 deletions lib/puppet/provider/iis_site/webadministration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,29 @@ def update

cmd << self.class.ps_script_content('serviceautostartprovider', @resource)

@resource[:authenticationinfo]&.each do |auth, _enable|
@resource[:authenticationinfo]&.each do |auth, enable|
args = []
args << "-Filter 'system.webserver/security/authentication/#{auth}Authentication'"
args << "-PSPath 'IIS:\\'"
args << "-Location '#{@resource[:name]}'"
args << '-Name enabled'
args << "-Value #{@resource[:authenticationinfo][auth]}"
if auth == 'forms'
# Handle formsAuthentication separately
mode_value = enable ? 'Forms' : 'None'
# For Forms authentication, we need to set the mode value
# in the system.web section, not the system.webserver section
args << "-Filter 'system.web/authentication'"

# This is a workaround for the fact that the WebAdministration module
# does not support setting the mode value for Forms authentication
# at the site level
args << "-PSPath 'IIS:\\Sites\\#{@resource[:name]}'"
args << "-Name 'mode'"
args << "-Value '#{mode_value}'"
else
# Handle other authentication types
args << "-Filter 'system.webserver/security/authentication/#{auth}Authentication'"
args << "-PSPath 'IIS:\\'"
args << "-Location '#{@resource[:name]}'"
args << '-Name enabled'
args << "-Value #{enable}"
end
cmd << "Set-WebConfigurationProperty #{args.join(' ')} -ErrorAction Stop\n"
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@ Get-WebSite | % {
'forms'
)
$authenticationTypes | Foreach-Object -Begin { $info = @{} } -Process {
$p = Get-WebConfiguration -Filter "system.webserver/security/authentication/$($_)Authentication" -PSPath "IIS:\sites\$($name)"
$info["$($_)"] = $p.enabled
if ($_ -eq 'forms') {
# Special handling for formsAuthentication
$p = Get-WebConfigurationProperty -Filter "system.web/authentication" -Name "mode" -PSPath "IIS:\Sites\$($name)" -ErrorAction SilentlyContinue
$info["$($_)"] = if ($p -eq 'Forms') { $true } else { $false }
} else {
# Handle other authentication types
$p = Get-WebConfiguration -Filter "system.webserver/security/authentication/$($_)Authentication" -PSPath "IIS:\sites\$($name)" -ErrorAction SilentlyContinue
$info["$($_)"] = $p.enabled
}
}
$authenticationinfo = New-Object -TypeName PSObject -Property $info

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Get-WebApplication | % {
clientCertificateMapping = [bool](Get-WebConfiguration -Location "${site}/${name}" -Filter "system.webserver/security/authentication/clientCertificateMappingAuthentication").enabled
iisClientCertificateMapping = [bool](Get-WebConfiguration -Location "${site}/${name}" -Filter "system.webserver/security/authentication/iisClientCertificateMappingAuthentication").enabled
windows = [bool](Get-WebConfiguration -Location "${site}/${name}" -Filter "system.webserver/security/authentication/windowsAuthentication").enabled
forms = [bool](Get-WebConfiguration -Location "${site}/${name}" -Filter "system.webserver/security/authentication/formsAuthentication").enabled
forms = [string](Get-WebConfigurationProperty -Location "${site}/${name}" -Filter "system.web/authentication" -Name "mode") -eq "Forms"
}
enabledprotocols = [string]$_.enabledProtocols
}
Expand Down
2 changes: 1 addition & 1 deletion metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"dependencies": [
{
"name": "puppetlabs/pwshlib",
"version_requirement": ">= 0.4.0 < 2.0.0"
"version_requirement": ">= 0.4.0 < 2.1.0"
}
],
"operatingsystem_support": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,61 @@

describe 'updating physicalpath'
describe 'updating sslflags'
describe 'updating authenticationinfo'
describe 'updating authenticationinfo for IIS_Application' do
let(:params) do
{
title: 'foo\bar',
name: 'foo\bar',
ensure: :present,
sitename: 'foo',
applicationname: 'bar',
applicationpool: 'DefaultAppPool',
enabledprotocols: 'http,https',
authenticationinfo: {
'anonymous' => true,
'basic' => false,
'clientCertificateMapping' => false,
'digest' => false,
'iisClientCertificateMapping' => false,
'windows' => true,
'forms' => false
},
}
end
let(:authenticationinfo) do
{
'anonymous' => true,
'basic' => false,
'clientCertificateMapping' => false,
'digest' => false,
'iisClientCertificateMapping' => false,
'windows' => false,
'forms' => true
}
end

before :each do
cmdtext = "$webApplication = Get-WebApplication -Site 'foo' -Name 'bar'"
cmdtext += "\n"
authenticationinfo.each do |auth, enable|
if auth == 'forms' # Forms authentication requires a different command
mode_value = enable ? 'Forms' : 'None'
cmdtext += "Set-WebConfigurationProperty -PSPath 'IIS:/Sites/foo/bar' " \
"-Filter 'system.web/authentication' -Name 'mode' -Value '#{mode_value}' -ErrorAction Stop\n"
else
cmdtext += "Set-WebConfigurationProperty -Location 'foo/bar' " \
"-Filter 'system.webserver/security/authentication/#{auth}Authentication' -Name enabled -Value #{enable} -ErrorAction Stop\n"
end
end
allow(Puppet::Provider::IIS_PowerShell).to receive(:run).and_return(exitcode: 0)
end

it 'updates value' do
iis_application_provider.authenticationinfo = authenticationinfo
iis_application_provider.update
end
end

describe 'updating enabledprotocols' do
let(:params) do
{
Expand Down
69 changes: 69 additions & 0 deletions spec/unit/puppet/provider/iis_site/webadministration_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'spec_helper'
require 'puppet/provider/iis_powershell'

describe Puppet::Type.type(:iis_site).provider(:webadministration) do
subject(:webadministration) { described_class.new }
Expand Down Expand Up @@ -57,4 +58,72 @@
end
end
end

context 'updating authenticationinfo for IIS_Site' do
let(:iis_site_resource) do
result = Puppet::Type.type(:iis_site).new(
name: 'foo',
ensure: :present,
physicalpath: 'C:\inetpub\wwwroot\foo',
applicationpool: 'MyAppPool',
enabledprotocols: 'http,https',
authenticationinfo: {
'anonymous' => true,
'basic' => false,
'clientCertificateMapping' => false,
'digest' => false,
'iisClientCertificateMapping' => false,
'windows' => false,
'forms' => true
},
)
result.provider = webadministration
result
end
let(:authenticationinfo) do
{
'anonymous' => true,
'basic' => false,
'clientCertificateMapping' => false,
'digest' => false,
'iisClientCertificateMapping' => false,
'windows' => false,
'forms' => true
}
end

before :each do
cmd = []
cmd << described_class.ps_script_content('_setwebsite', iis_site_resource)
cmd << described_class.ps_script_content('trysetitemproperty', iis_site_resource)
cmd << described_class.ps_script_content('generalproperties', iis_site_resource)
cmd << described_class.ps_script_content('bindingproperty', iis_site_resource)
cmd << described_class.ps_script_content('logproperties', iis_site_resource)
cmd << described_class.ps_script_content('limitsproperty', iis_site_resource)
cmd << described_class.ps_script_content('serviceautostartprovider', iis_site_resource)
authenticationinfo.each do |auth, enable|
args = []
if auth == 'forms' # Forms authentication requires a different command
mode_value = enable ? 'Forms' : 'None'
args << "-Filter 'system.web/authentication'"
args << "-PSPath 'IIS:\\Sites\\foo'"
args << "-Name 'mode'"
args << "-Value '#{mode_value}'"
else
args << "-Filter 'system.webserver/security/authentication/#{auth}Authentication'"
args << "-PSPath 'IIS:\\'"
args << "-Location 'foo'"
args << '-Name enabled'
args << "-Value #{enable}"
end
cmd << "Set-WebConfigurationProperty #{args.join(' ')} -ErrorAction Stop\n"
end
allow(Puppet::Provider::IIS_PowerShell).to receive(:run).and_return(exitcode: 0)
end

it 'updates value' do
webadministration.authenticationinfo = authenticationinfo
webadministration.update
end
end
end
Loading