Skip to content

Commit 9f7f38f

Browse files
committed
Add mod_auth_openidc to the supported modules
1 parent ebfb108 commit 9f7f38f

File tree

7 files changed

+290
-0
lines changed

7 files changed

+290
-0
lines changed

manifests/mod/auth_openidc.pp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# @summary
2+
# Installs and configures `mod_auth_openidc`.
3+
#
4+
# @see https://github.com/zmartzone/mod_auth_openidc for additional documentation.
5+
#
6+
class apache::mod::auth_openidc (
7+
) inherits ::apache::params {
8+
9+
include ::apache
10+
include ::apache::mod::authz_user
11+
apache::mod { 'auth_openidc': }
12+
13+
}

manifests/params.pp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@
205205
'auth_kerb' => 'mod_auth_kerb',
206206
'auth_gssapi' => 'mod_auth_gssapi',
207207
'auth_mellon' => 'mod_auth_mellon',
208+
'auth_openidc' => 'mod_auth_openidc',
208209
'authnz_ldap' => $::apache::version::distrelease ? {
209210
'7' => 'mod_ldap',
210211
default => 'mod_authz_ldap',
@@ -343,6 +344,7 @@
343344
$mod_packages = {
344345
'auth_cas' => 'libapache2-mod-auth-cas',
345346
'auth_kerb' => 'libapache2-mod-auth-kerb',
347+
'auth_openidc' => 'libapache2-mod-auth-openidc',
346348
'auth_gssapi' => 'libapache2-mod-auth-gssapi',
347349
'auth_mellon' => 'libapache2-mod-auth-mellon',
348350
'authnz_pam' => 'libapache2-mod-authnz-pam',
@@ -376,6 +378,7 @@
376378
$mod_packages = {
377379
'auth_cas' => 'libapache2-mod-auth-cas',
378380
'auth_kerb' => 'libapache2-mod-auth-kerb',
381+
'auth_openidc' => 'libapache2-mod-auth-openidc',
379382
'auth_gssapi' => 'libapache2-mod-auth-gssapi',
380383
'auth_mellon' => 'libapache2-mod-auth-mellon',
381384
'authnz_pam' => 'libapache2-mod-authnz-pam',
@@ -403,6 +406,7 @@
403406
$mod_packages = {
404407
'auth_cas' => 'libapache2-mod-auth-cas',
405408
'auth_kerb' => 'libapache2-mod-auth-kerb',
409+
'auth_openidc' => 'libapache2-mod-auth-openidc',
406410
'auth_gssapi' => 'libapache2-mod-auth-gssapi',
407411
'auth_mellon' => 'libapache2-mod-auth-mellon',
408412
'authnz_pam' => 'libapache2-mod-authnz-pam',
@@ -578,6 +582,7 @@
578582
# NOTE: not sure where the shibboleth should come from
579583
'auth_kerb' => 'www/mod_auth_kerb2',
580584
'auth_gssapi' => 'www/mod_auth_gssapi',
585+
'auth_openidc'=> 'www/mod_auth_openidc',
581586
'fcgid' => 'www/mod_fcgid',
582587
'passenger' => 'www/rubygem-passenger',
583588
'perl' => 'www/mod_perl2',

manifests/vhost.pp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,6 +1626,12 @@
16261626
# this lets you define configuration variables inside a vhost using [`Define`](https://httpd.apache.org/docs/2.4/mod/core.html#define),
16271627
# these can then be used to replace configuration values. All Defines are Undefined at the end of the VirtualHost.
16281628
#
1629+
# @param auth_oidc
1630+
# Enable `mod_auth_openidc` parameters for OpenID Connect authentication.
1631+
#
1632+
# @param oidc_settings
1633+
# An Apache::OIDCSettings Struct containing (mod_auth_openidc settings)[https://github.com/zmartzone/mod_auth_openidc/blob/master/auth_openidc.conf].
1634+
#
16291635
define apache::vhost(
16301636
Variant[Boolean,String] $docroot,
16311637
$manage_docroot = true,
@@ -1855,6 +1861,8 @@
18551861
Optional[Enum['On', 'on', 'Off', 'off', 'DNS', 'dns']] $use_canonical_name = undef,
18561862
Optional[Variant[String,Array[String]]] $comment = undef,
18571863
Hash $define = {},
1864+
Boolean $auth_oidc = false,
1865+
Optional[Apache::OIDCSettings] $oidc_settings = undef,
18581866
) {
18591867

18601868
# The base class must be included first because it is used by parameter defaults
@@ -1901,6 +1909,10 @@
19011909
include ::apache::mod::auth_kerb
19021910
}
19031911

1912+
if $auth_oidc and $ensure == 'present' {
1913+
include ::apache::mod::auth_openidc
1914+
}
1915+
19041916
if $virtual_docroot {
19051917
include ::apache::mod::vhost_alias
19061918
}
@@ -2716,6 +2728,17 @@
27162728
}
27172729
}
27182730

2731+
# Template uses:
2732+
# - $auth_oidc
2733+
# - $oidc_settings
2734+
if $auth_oidc {
2735+
concat::fragment { "${name}-auth_oidc":
2736+
target => "${priority_real}${filename}.conf",
2737+
order => 360,
2738+
content => template('apache/vhost/_auth_oidc.erb'),
2739+
}
2740+
}
2741+
27192742
# Template uses:
27202743
# - $shib_compat_valid_user
27212744
if $shibboleth_enabled {
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
require 'spec_helper'
2+
3+
describe 'apache::mod::auth_openidc', type: :class do
4+
it_behaves_like 'a mod class, without including apache'
5+
6+
context 'default configuration with parameters' do
7+
context 'on a Debian OS', :compile do
8+
let :facts do
9+
{
10+
id: 'root',
11+
kernel: 'Linux',
12+
lsbdistcodename: 'jessie',
13+
osfamily: 'Debian',
14+
operatingsystem: 'Debian',
15+
operatingsystemrelease: '8',
16+
path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
17+
is_pe: false,
18+
}
19+
end
20+
21+
it { is_expected.to contain_class('apache::params') }
22+
it { is_expected.to contain_apache__mod('auth_openidc') }
23+
it { is_expected.to contain_package('libapache2-mod-auth-openidc') }
24+
end
25+
context 'on a RedHat OS', :compile do
26+
let :facts do
27+
{
28+
id: 'root',
29+
kernel: 'Linux',
30+
osfamily: 'RedHat',
31+
operatingsystem: 'RedHat',
32+
operatingsystemrelease: '6',
33+
path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
34+
is_pe: false,
35+
}
36+
end
37+
38+
it { is_expected.to contain_class('apache::params') }
39+
it { is_expected.to contain_apache__mod('auth_openidc') }
40+
it { is_expected.to contain_package('mod_auth_openidc') }
41+
end
42+
context 'on a FreeBSD OS', :compile do
43+
let :facts do
44+
{
45+
id: 'root',
46+
kernel: 'FreeBSD',
47+
osfamily: 'FreeBSD',
48+
operatingsystem: 'FreeBSD',
49+
operatingsystemrelease: '9',
50+
path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
51+
is_pe: false,
52+
}
53+
end
54+
55+
it { is_expected.to contain_class('apache::params') }
56+
it { is_expected.to contain_apache__mod('auth_openidc') }
57+
it { is_expected.to contain_package('www/mod_auth_openidc') }
58+
end
59+
end
60+
context 'overriding mod_packages' do
61+
context 'on a RedHat OS', :compile do
62+
let :facts do
63+
{
64+
id: 'root',
65+
kernel: 'Linux',
66+
osfamily: 'RedHat',
67+
operatingsystem: 'RedHat',
68+
operatingsystemrelease: '6',
69+
path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
70+
is_pe: false,
71+
}
72+
end
73+
let :pre_condition do
74+
<<-MANIFEST
75+
include apache::params
76+
class { 'apache':
77+
mod_packages => merge($::apache::params::mod_packages, {
78+
'auth_openidc' => 'httpd24-mod_auth_openidc',
79+
})
80+
}
81+
MANIFEST
82+
end
83+
84+
it { is_expected.to contain_apache__mod('auth_openidc') }
85+
it { is_expected.to contain_package('httpd24-mod_auth_openidc') }
86+
it { is_expected.not_to contain_package('mod_auth_openidc') }
87+
end
88+
end
89+
end

spec/defines/vhost_spec.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,14 @@
458458
'max_keepalive_requests' => '1000',
459459
'protocols' => ['h2', 'http/1.1'],
460460
'protocols_honor_order' => true,
461+
'auth_oidc' => true,
462+
'oidc_settings' => { 'ProviderMetadataURL' => 'https://login.example.com/.well-known/openid-configuration',
463+
'ClientID' => 'test',
464+
'RedirectURI' => 'https://login.example.com/redirect_uri',
465+
'ProviderTokenEndpointAuth' => 'client_secret_basic',
466+
'RemoteUserClaim' => 'sub',
467+
'ClientSecret' => 'aae053a9-4abf-4824-8956-e94b2af335c8',
468+
'CryptoPassphrase' => '4ad1bb46-9979-450e-ae58-c696967df3cd' },
461469
}
462470
end
463471

@@ -1378,6 +1386,41 @@
13781386
content: %r{^\s+PassengerLveMinUid\s500$},
13791387
)
13801388
}
1389+
it {
1390+
is_expected.to contain_concat__fragment('rspec.example.com-auth_oidc').with(
1391+
content: %r{^\s+OIDCProviderMetadataURL\shttps:\/\/login.example.com\/\.well-known\/openid-configuration$},
1392+
)
1393+
}
1394+
it {
1395+
is_expected.to contain_concat__fragment('rspec.example.com-auth_oidc').with(
1396+
content: %r{^\s+OIDCClientID\stest$},
1397+
)
1398+
}
1399+
it {
1400+
is_expected.to contain_concat__fragment('rspec.example.com-auth_oidc').with(
1401+
content: %r{^\s+OIDCRedirectURI\shttps:\/\/login\.example.com\/redirect_uri$},
1402+
)
1403+
}
1404+
it {
1405+
is_expected.to contain_concat__fragment('rspec.example.com-auth_oidc').with(
1406+
content: %r{^\s+OIDCProviderTokenEndpointAuth\sclient_secret_basic$},
1407+
)
1408+
}
1409+
it {
1410+
is_expected.to contain_concat__fragment('rspec.example.com-auth_oidc').with(
1411+
content: %r{^\s+OIDCRemoteUserClaim\ssub$},
1412+
)
1413+
}
1414+
it {
1415+
is_expected.to contain_concat__fragment('rspec.example.com-auth_oidc').with(
1416+
content: %r{^\s+OIDCClientSecret\saae053a9-4abf-4824-8956-e94b2af335c8$},
1417+
)
1418+
}
1419+
it {
1420+
is_expected.to contain_concat__fragment('rspec.example.com-auth_oidc').with(
1421+
content: %r{^\s+OIDCCryptoPassphrase\s4ad1bb46-9979-450e-ae58-c696967df3cd$},
1422+
)
1423+
}
13811424
end
13821425
context 'vhost with multiple ip addresses' do
13831426
let :params do

templates/vhost/_auth_oidc.erb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<% if @auth_oidc -%>
2+
<% @oidc_settings.each do |key, value| %>
3+
OIDC<%= key %> <%= value -%>
4+
<% end %>
5+
<% end -%>

types/oidcsettings.pp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# https://github.com/zmartzone/mod_auth_openidc/blob/master/auth_openidc.conf
2+
type Apache::OIDCSettings = Struct[
3+
{
4+
Optional['RedirectURI'] => Variant[Stdlib::HTTPSUrl,Stdlib::HttpUrl],
5+
Optional['CryptoPassphrase'] => String,
6+
Optional['MetadataDir'] => String,
7+
Optional['ProviderMetadataURL'] => Stdlib::HTTPSUrl,
8+
Optional['ProviderIssuer'] => String,
9+
Optional['ProviderAuthorizationEndpoint'] => Stdlib::HTTPSUrl,
10+
Optional['ProviderJwksUri'] => Stdlib::HTTPSUrl,
11+
Optional['ProviderTokenEndpoint'] => Stdlib::HTTPSUrl,
12+
Optional['ProviderTokenEndpointAuth'] => Enum['client_secret_basic','client_secret_post','client_secret_jwt','private_key_jwt','none'],
13+
Optional['ProviderTokenEndpointParams'] => Pattern['/^[A-Za-z0-9\-\._%]+=[A-Za-z0-9\-\._%]+(&[A-Za-z0-9\-\._%]+=[A-Za-z0-9\-\._%]+)*$/'],
14+
Optional['ProviderUserInfoEndpoint'] => Stdlib::HTTPSUrl,
15+
Optional['ProviderCheckSessionIFrame'] => Stdlib::HTTPSUrl,
16+
Optional['ProviderEndSessionEndpoint'] => Stdlib::HTTPSUrl,
17+
Optional['ProviderRevocationEndpoint'] => Stdlib::HTTPSUrl,
18+
Optional['ProviderBackChannelLogoutSupported'] => Enum['On','Off'],
19+
Optional['ProviderRegistrationEndpointJson'] => String,
20+
Optional['Scope'] => Pattern['/^[A-Za-z0-9\-\._\s]+$/'],
21+
Optional['AuthRequestParams'] => Pattern['/^[A-Za-z0-9\-\._%]+=[A-Za-z0-9\-\._%]+(&[A-Za-z0-9\-\._%]+=[A-Za-z0-9\-\._%]+)*$/'],
22+
Optional['SSLValidateServer'] => Enum['On','Off'],
23+
Optional['UserInfoRefreshInterval'] => Integer,
24+
Optional['JWKSRefreshInterval'] => Interger,
25+
Optional['UserInfoTokenMethod'] => Enum['authz_header','post_param'],
26+
Optional['ProviderAuthRequestMethod'] => Enum['GET','POST'],
27+
Optional['PublicKeyFiles'] => String,
28+
Optional['ResponseType'] => Enum['code','id_token','id_token token','code id_token','code token','code id_token token'],
29+
Optional['ResponseMode'] => Enum['fragment','query','form_post'],
30+
Optional['ClientID'] => String,
31+
Optional['ClientSecret'] => String,
32+
Optional['ClientTokenEndpointCert'] => String,
33+
Optional['ClientTokenEndpointKey'] => String,
34+
Optional['ClientName'] => String,
35+
Optional['ClientContact'] => String,
36+
Optional['PKCDMethod'] => Enum['plain','S256','referred_tb'],
37+
Optional['TokenBindingPolicy'] => Enum['disabled','optional','required','enforced'],
38+
Optional['ClientJwksUri'] => Stdlib::HTTPSUrl,
39+
Optional['IDTokenSignedResponseAlg'] => Enum['RS256','RS384','RS512','PS256','PS384','PS512','HS256','HS384','HS512','ES256','ES384','ES512'],
40+
Optional['IDTokenEncryptedResponseAlg'] => Enum['RSA1_5','A128KW','A256KW','RSA-OAEP'],
41+
Optional['IDTokenEncryptedResponseAlg'] => Enum['A128CBC-HS256','A256CBC-HS512','A256GCM'],
42+
Optional['UserInfoSignedResposeAlg'] => Enum['RS256','RS384','RS512','PS256','PS384','PS512','HS256','HS384','HS512','ES256','ES384','ES512'],
43+
Optional['UserInfoEncryptedResponseAlg'] => Enum['RSA1_5','A128KW','A256KW','RSA-OAEP'],
44+
Optional['UserInfoEncryptedResponseEnc'] => Enum['A128CBC-HS256','A256CBC-HS512','A256GCM'],
45+
Optional['OAuthServerMetadataURL'] => Stdlib::HTTPSUrl,
46+
Optional['AuthIntrospectionEndpoint'] => Stdlib::HTTPSUrl,
47+
Optional['OAuthClientID'] => String,
48+
Optional['OAuthClientSecret'] => String,
49+
Optional['OAuthIntrospectionEndpointAuth'] => Enum['client_secret_basic','client_secret_post','client_secret_jwt','private_key_jwt','bearer_access_token','none'],
50+
Optional['OAuthIntrospectionClientAuthBearerToken'] => String,
51+
Optional['OAuthIntrospectionEndpointCert'] => String,
52+
Optional['OAuthIntrospectionEndpointKey'] => String,
53+
Optional['OAuthIntrospectionEndpointMethod'] => Enum['POST','GET'],
54+
Optional['OAuthIntrospectionEndpointParams'] => Pattern['/^[A-Za-z0-9\-\._%]+=[A-Za-z0-9\-\._%]+(&[A-Za-z0-9\-\._%]+=[A-Za-z0-9\-\._%]+)*$/'],
55+
Optional['OAuthIntrospectionTokenParamName'] => String,
56+
Optional['OAuthTokenExpiryClaim'] => Pattern['/^[A-Za-z0-9\-\._]+\s(absolute|relative)\s(mandatory|optional)$/'],
57+
Optional['OAuthSSLValidateServer'] => Enum['On','Off'],
58+
Optional['OAuthVerifySharedKeys'] => String,
59+
Optional['OAuthVerifyCertFiles'] => String,
60+
Optional['OAuthVerifyJwksUri'] => Stdlib::HTTPSUrl,
61+
Optional['OAuthRemoteUserClaim'] => String,
62+
Optional['OAuthAcceptTokenAs'] => Pattern['/^((header|post|query|cookie\:[A-Za-z0-9\-\._]+|basic)\s?)+$/'],
63+
Optional['OAuthAccessTokenBindingPolicy'] => Enum['disabled','optional','required','enforced'],
64+
Optional['Cookie'] => String,
65+
Optional['SessionCookieChunkSize'] => Integer,
66+
Optional['CookieHTTPOnly'] => Enum['On','Off'],
67+
Optional['CookieSameSite'] => Enum['On','Off'],
68+
Optional['PassCookies'] => String,
69+
Optional['StripCookies'] => String,
70+
Optional['StateMaxNumberOfCookies'] => Pattern['/^[0-9]+\s(false|true)$/'],
71+
Optional['SessionInactivityTimeout'] => Integer,
72+
Optional['SessionMaxDuration'] => Integer,
73+
Optional['SessionType'] => Pattern['/^(server-cache(:persistent)?|client-cookie(:persistent)?)$/'],
74+
Optional['SessionCacheFallbackToCookie'] => Enum['On','Off'],
75+
Optional['CacheType'] => Enum['shm','memcache','file','redis'],
76+
Optional['CacheEncrypt'] => Enum['On','Off'],
77+
Optional['CacheShmMax'] => Integer,
78+
Optional['CacheShmEntrySizeMax'] => Integer,
79+
Optional['CacheFileCleanInterval'] => Integer,
80+
Optional['MemCacheServers'] => String,
81+
Optional['RedisCacheServer'] => String,
82+
Optional['RedisCachePassword'] => String,
83+
Optional['DiscoverURL'] => Variant[Stdlib::HTTPSUrl,Stdlib::HttpUrl],
84+
Optional['HTMLErrorTemplate'] => String,
85+
Optional['DefaultURL'] => Variant[Stdlib::HTTPSUrl,Stdlib::HttpUrl],
86+
Optional['PathScope'] => Pattern['/^[A-Za-z0-9\-\._\s]+$/'],
87+
Optional['PathAuthRequestParams'] => Pattern['/^[A-Za-z0-9\-\._%]+=[A-Za-z0-9\-\._%]+(&[A-Za-z0-9\-\._%]+=[A-Za-z0-9\-\._%]+)*$/'],
88+
Optional['IDTokenIatSlack'] => Integer,
89+
Optional['ClaimPrefix'] => String,
90+
Optional['ClaimDelimiter'] => Pattern['/^.$/'],
91+
Optional['RemoteUserClaim'] => String,
92+
Optional['PassIDTokenAs'] => Pattern['/^((claims|payload|serialized)\s?)+$/'],
93+
Optional['PassUserInfoAs'] => Pattern['/^((claims|json|jwt)\s?)+$/'],
94+
Optional['PassClaimsAs'] => Enum['none','headers','environment','both'],
95+
Optional['AuthNHeader'] => String,
96+
Optional['HTTPTimeoutLong'] => Integer,
97+
Optional['HTTPTimeoutShort'] => Integer,
98+
Optional['StateTimeout'] => Integer,
99+
Optional['ScrubRequestHeaders'] => Enum['On','Off'],
100+
Optional['OutgoingProxy'] => String,
101+
Optional['UnAuthAction'] => Enum['auth','pass','401','410'],
102+
Optional['UnAuthzAction'] => Enum['401','403','auth'],
103+
Optional['PreservePost'] => Enum['On','Off'],
104+
Optional['PassRefreshToken'] => Enum['On','Off'],
105+
Optional['RequestObject'] => String,
106+
Optional['ProviderMetadataRefreshInterval'] => Integer,
107+
Optional['InfoHook'] => Pattern['/^((iat|access_token|access_token_expires|id_token|userinfo|refresh_token|session)\s?)+$/'],
108+
Optional['BlackListedClaims'] => String,
109+
Optional['WhiteListedClaims'] => String,
110+
Optional['RefreshAccessTokenBeforeExpiry'] => Pattern['/^[0-9]+(\slogout_on_error)?$/'],
111+
}
112+
]

0 commit comments

Comments
 (0)