New Issuer::CAS (#1183)
This commit is contained in:
parent
d1d57fae22
commit
b83374b274
|
@ -24,7 +24,7 @@ our $specialNodeHash = {
|
|||
our $doubleHashKeys = 'issuerDBGetParameters';
|
||||
our $simpleHashKeys = '(?:(?:l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|c(?:as(?:StorageOption|Attribute)|ustomAddParam|ombModule)|(?:(?:d(?:emo|bi)|facebook|webID)E|e)xportedVar|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|p(?:ersistentStorageOption|ortalSkinRule)|re(?:moteGlobalStorageOption|loadUrl)|macro)s|o(?:idcS(?:erviceMetaDataAuthnContext|torageOptions)|penIdExportedVars)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember)|a(?:uthChoiceModules|pplicationList)|S(?:MTPTLSOpts|SLVarIf))';
|
||||
our $specialNodeKeys = '(?:(?:(?:saml(?:ID|S)|oidc[OR])P|cas(?:App|Srv))MetaDataNode|virtualHost)s';
|
||||
our $casAppMetaDataNodeKeys = 'casAppMetaData(?:OptionsService|ExportedVars)';
|
||||
our $casAppMetaDataNodeKeys = 'casAppMetaData(?:Options(?:Servic|Rul)e|ExportedVars)';
|
||||
our $casSrvMetaDataNodeKeys = 'casSrvMetaData(?:Options(?:ProxiedServices|DisplayName|Gateway|Renew|Icon|Url)|ExportedVars)';
|
||||
our $oidcOPMetaDataNodeKeys = 'oidcOPMetaData(?:Options(?:C(?:lient(?:Secret|ID)|heckJWTSignature|onfigurationURI)|TokenEndpointAuthMethod|(?:JWKSTimeou|Promp)t|I(?:DTokenMaxAge|con)|S(?:toreIDToken|cope)|U(?:iLocales|seNonce)|Display(?:Name)?|AcrValues|MaxAge)|ExportedVars|J(?:SON|WKS))';
|
||||
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:I(?:DToken(?:Expiration|SignAlg)|con)|Logout(?:SessionRequired|Type|Url)|AccessTokenExpiration|R(?:edirectUris|ule)|Client(?:Secret|ID)|BypassConsent|DisplayName|ExtraClaims|UserIDAttr)|ExportedVars)';
|
||||
|
@ -67,6 +67,5 @@ our $issuerParameters = {
|
|||
};
|
||||
our $samlServiceParameters = [qw(samlEntityID samlServicePrivateKeySig samlServicePrivateKeySigPwd samlServicePublicKeySig samlServicePrivateKeyEnc samlServicePrivateKeyEncPwd samlServicePublicKeyEnc samlServiceUseCertificateInResponse samlNameIDFormatMapEmail samlNameIDFormatMapX509 samlNameIDFormatMapWindows samlNameIDFormatMapKerberos samlAuthnContextMapPassword samlAuthnContextMapPasswordProtectedTransport samlAuthnContextMapTLSClient samlAuthnContextMapKerberos samlOrganizationDisplayName samlOrganizationName samlOrganizationURL samlSPSSODescriptorAuthnRequestsSigned samlSPSSODescriptorWantAssertionsSigned samlSPSSODescriptorSingleLogoutServiceHTTPRedirect samlSPSSODescriptorSingleLogoutServiceHTTPPost samlSPSSODescriptorSingleLogoutServiceSOAP samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact samlSPSSODescriptorAssertionConsumerServiceHTTPPost samlSPSSODescriptorArtifactResolutionServiceArtifact samlIDPSSODescriptorWantAuthnRequestsSigned samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect samlIDPSSODescriptorSingleSignOnServiceHTTPPost samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect samlIDPSSODescriptorSingleLogoutServiceHTTPPost samlIDPSSODescriptorSingleLogoutServiceSOAP samlIDPSSODescriptorArtifactResolutionServiceArtifact samlAttributeAuthorityDescriptorAttributeServiceSOAP samlIdPResolveCookie samlMetadataForceUTF8 samlStorage samlStorageOptions samlRelayStateTimeout samlUseQueryStringSpecific samlCommonDomainCookieActivation samlCommonDomainCookieDomain samlCommonDomainCookieReader samlCommonDomainCookieWriter)];
|
||||
our $oidcServiceParameters = [qw(oidcServiceMetaDataIssuer oidcServiceMetaDataAuthorizeURI oidcServiceMetaDataTokenURI oidcServiceMetaDataUserInfoURI oidcServiceMetaDataJWKSURI oidcServiceMetaDataRegistrationURI oidcServiceMetaDataEndSessionURI oidcServiceMetaDataCheckSessionURI oidcServiceMetaDataFrontChannelURI oidcServiceMetaDataBackChannelURI oidcServiceMetaDataAuthnContext oidcServicePrivateKeySig oidcServicePublicKeySig oidcServiceKeyIdSig oidcServiceAllowDynamicRegistration oidcServiceAllowAuthorizationCodeFlow oidcServiceAllowImplicitFlow oidcServiceAllowHybridFlow oidcStorage oidcStorageOptions)];
|
||||
our $casServiceParameters = [qw()];
|
||||
|
||||
1;
|
||||
|
|
|
@ -640,6 +640,25 @@ sub attributes {
|
|||
'casAppMetaDataOptions' => {
|
||||
'type' => 'subContainer'
|
||||
},
|
||||
'casAppMetaDataOptionsRule' => {
|
||||
'test' => sub {
|
||||
my ( $val, $conf ) = @_;
|
||||
my $s = '';
|
||||
|
||||
BEGIN {
|
||||
${^WARNING_BITS} =
|
||||
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55";
|
||||
}
|
||||
eval "$s $val";
|
||||
my $err = join(
|
||||
'',
|
||||
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
|
||||
split( /\n/, $@, 0 ) )
|
||||
);
|
||||
return $err ? ( 1, "__badExpression__: $err" ) : 1;
|
||||
},
|
||||
'type' => 'text'
|
||||
},
|
||||
'casAppMetaDataOptionsService' => {
|
||||
'type' => 'url'
|
||||
},
|
||||
|
|
|
@ -214,7 +214,7 @@ EOF
|
|||
}
|
||||
print F "$tmp};\n";
|
||||
}
|
||||
foreach (qw(samlServiceParameters oidcServiceParameters casServiceParameters)) {
|
||||
foreach (qw(samlServiceParameters oidcServiceParameters)) {
|
||||
no strict 'refs';
|
||||
$tmp = "our \$$_ = [qw(" . join( ' ', @$$_ ) . ")];\n";
|
||||
print F "$tmp";
|
||||
|
|
|
@ -1237,16 +1237,21 @@ sub attributes {
|
|||
},
|
||||
|
||||
# Partners
|
||||
casAppMetaDataOptions => { type => 'subContainer', },
|
||||
casAppMetaDataOptions => { type => 'subContainer', },
|
||||
casAppMetaDataExportedVars => {
|
||||
type => 'keyTextContainer',
|
||||
default => { cn => 'cn', mail => 'mail', uid => 'uid', },
|
||||
documentation => 'CAS exported variables',
|
||||
},
|
||||
casAppMetaDataOptionsService => {
|
||||
type => 'url',
|
||||
type => 'url',
|
||||
documentation => 'CAS App service',
|
||||
},
|
||||
casAppMetaDataOptionsRule => {
|
||||
type => 'text',
|
||||
test => $perlExpr,
|
||||
documentation => 'CAS App rule',
|
||||
},
|
||||
|
||||
# Fake attribute: used by manager REST API to agglomerate all nodes
|
||||
# related to a SAML SP partner
|
||||
|
@ -2083,7 +2088,7 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
|||
default => { cn => 'cn', mail => 'mail', uid => 'uid', },
|
||||
documentation => 'CAS exported variables',
|
||||
},
|
||||
casSrvMetaDataOptions => { type => 'subContainer', },
|
||||
casSrvMetaDataOptions => { type => 'subContainer', },
|
||||
casSrvMetaDataOptionsGateway => { type => 'bool', },
|
||||
casSrvMetaDataOptionsProxiedServices => {
|
||||
type => 'keyTextContainer',
|
||||
|
@ -2097,11 +2102,11 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
|||
msgFail => '__badUrl__',
|
||||
},
|
||||
casSrvMetaDataOptionsDisplayName => {
|
||||
type => 'text',
|
||||
type => 'text',
|
||||
documentation => 'Name to display for CAS server',
|
||||
},
|
||||
casSrvMetaDataOptionsIcon => {
|
||||
type => 'text',
|
||||
type => 'text',
|
||||
documentation => 'Path of CAS Server Icon',
|
||||
},
|
||||
|
||||
|
|
|
@ -231,7 +231,10 @@ sub cTrees {
|
|||
casAppMetaDataNode => [
|
||||
{
|
||||
title => 'casAppMetaDataOptions',
|
||||
nodes => ['casAppMetaDataOptionsService']
|
||||
nodes => [
|
||||
'casAppMetaDataOptionsService',
|
||||
'casAppMetaDataOptionsRule'
|
||||
]
|
||||
},
|
||||
'casAppMetaDataExportedVars',
|
||||
],
|
||||
|
|
|
@ -16,6 +16,11 @@ function templates(tpl,key) {
|
|||
"get" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsService",
|
||||
"id" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsService",
|
||||
"title" : "casAppMetaDataOptionsService"
|
||||
},
|
||||
{
|
||||
"get" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsRule",
|
||||
"id" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsRule",
|
||||
"title" : "casAppMetaDataOptionsRule"
|
||||
}
|
||||
],
|
||||
"id" : "casAppMetaDataOptions",
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -108,6 +108,7 @@
|
|||
"casAppMetaDataNodes": "CAS Applications",
|
||||
"casAppMetaDataOptions": "Options",
|
||||
"casAppMetaDataOptionsService": "Service URL",
|
||||
"casAppMetaDataOptionsRule": "Rule",
|
||||
"casAppName": "CAS App Name",
|
||||
"casAttr": "CAS login",
|
||||
"casAttributes": "CAS exported attributes",
|
||||
|
|
|
@ -108,6 +108,7 @@
|
|||
"casAppMetaDataNodes": "Applications CAS",
|
||||
"casAppMetaDataOptions": "Options",
|
||||
"casAppMetaDataOptionsService": "URL du service",
|
||||
"casAppMetaDataOptionsRule": "Règle",
|
||||
"casAppName": "Nom de l'application CAS",
|
||||
"casAttr": "Identifiant CAS",
|
||||
"casAttributes": "Attributs CAS",
|
||||
|
|
|
@ -27,6 +27,7 @@ sub init {
|
|||
|
||||
# Launch parents initialization subroutines, then launch IdP en SP lists
|
||||
my $res = $self->Lemonldap::NG::Portal::Main::Issuer::init();
|
||||
return 0 unless($self->loadApp);
|
||||
$self->addUnauthRoute(
|
||||
( $self->path ) => {
|
||||
serviceValidate => 'serviceValidate',
|
||||
|
@ -108,35 +109,37 @@ sub run {
|
|||
"CAS access control requested on service $service");
|
||||
|
||||
## HERE
|
||||
unless ( $service =~ m#^https?://([^/]+)(/.*)?$# ) {
|
||||
unless ( $service =~ m#^(https?://[^/]+)(/.*)?$# ) {
|
||||
$self->logger->error("Bad service $service");
|
||||
return PE_ERROR;
|
||||
}
|
||||
my ( $host, $uri ) = ( $1, $2 );
|
||||
if (
|
||||
$self->p->HANDLER->grant(
|
||||
$req, $req->sessionInfo, $1, undef, $2
|
||||
)
|
||||
)
|
||||
{
|
||||
$self->logger->debug("CAS service $service access allowed");
|
||||
my $app;
|
||||
unless($app = $self->casAppList->{$host} ) {
|
||||
$self->userLogger->error('CAS service not configured');
|
||||
return PE_CAS_SERVICE_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
else {
|
||||
$self->userLogger->error(
|
||||
"CAS service $service access not allowed");
|
||||
|
||||
if ( $casAccessControlPolicy =~ /^(error)$/i ) {
|
||||
$self->logger->debug(
|
||||
"Return error instead of redirecting user on CAS service"
|
||||
);
|
||||
return PE_CAS_SERVICE_NOT_ALLOWED;
|
||||
if ( my $rule = $self->appRules->{$app} ) {
|
||||
if($rule->($req, $req->sessionInfo ) ) {
|
||||
$self->logger->debug("CAS service $service access allowed");
|
||||
}
|
||||
|
||||
else {
|
||||
$self->logger->debug(
|
||||
"Redirect user on CAS service with a fake ticket");
|
||||
$casServiceTicket = "ST-F4K3T1CK3T";
|
||||
$self->userLogger->error(
|
||||
"CAS service $service access not allowed");
|
||||
|
||||
if ( $casAccessControlPolicy =~ /^(error)$/i ) {
|
||||
$self->logger->debug(
|
||||
"Return error instead of redirecting user on CAS service"
|
||||
);
|
||||
return PE_CAS_SERVICE_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
else {
|
||||
$self->logger->debug(
|
||||
"Redirect user on CAS service with a fake ticket");
|
||||
$casServiceTicket = "ST-F4K3T1CK3T";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ has ua => (
|
|||
|
||||
has casSrvList => ( is => 'rw', default => sub { {} }, );
|
||||
has casAppList => ( is => 'rw', default => sub { {} }, );
|
||||
has appRules => ( is => 'rw', default => sub { {} }, );
|
||||
|
||||
# RUNNING METHODS
|
||||
|
||||
|
@ -50,9 +51,21 @@ sub loadApp {
|
|||
}
|
||||
foreach ( keys %{ $self->conf->{casAppMetaDataOptions} } ) {
|
||||
my $tmp =
|
||||
$self->conf->{casAppMetaDataOptions}->{casAppMetaDataOptionsService};
|
||||
$self->conf->{casAppMetaDataOptions}->{$_}
|
||||
->{casAppMetaDataOptionsService};
|
||||
$tmp =~ s#^(https?://[^/]+).*$#$1#;
|
||||
$self->casAppList->{$tmp} = $_;
|
||||
my $rule = $self->conf->{casAppMetaDataOptions}->{$_}
|
||||
->{casAppMetaDataOptionsRule};
|
||||
if ( length $rule ) {
|
||||
$rule = $self->p->HANDLER->substitute($rule);
|
||||
unless ( $rule = $self->p->HANDLER->buildSub($rule) ) {
|
||||
$self->error( 'OIDC RP rule error: '
|
||||
. $self->p->HANDLER->tsv->{jail}->error );
|
||||
return 0;
|
||||
}
|
||||
$self->appRules->{$_} = $rule;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -315,7 +328,7 @@ sub validateST {
|
|||
|
||||
my $proxied = $srvConf->{casSrvMetaDataOptionsProxiedServices} || {};
|
||||
my $proxy_url;
|
||||
if(%$proxied) {
|
||||
if (%$proxied) {
|
||||
$proxy_url = $self->p->fullUrl($req) . '?casProxy=1';
|
||||
if ( $self->conf->{authChoiceParam}
|
||||
and my $tmp = $req->param( $self->conf->{authChoiceParam} ) )
|
||||
|
@ -327,7 +340,7 @@ sub validateST {
|
|||
|
||||
$req->datas->{casProxyUrl} = $proxy_url;
|
||||
|
||||
$serviceValidateUrl .= "&pgtUrl=" . uri_escape( $proxy_url );
|
||||
$serviceValidateUrl .= "&pgtUrl=" . uri_escape($proxy_url);
|
||||
}
|
||||
|
||||
my $response = $self->ua->get($serviceValidateUrl);
|
||||
|
@ -348,7 +361,7 @@ sub validateST {
|
|||
}
|
||||
|
||||
# Get proxy data and store pgtId
|
||||
if ( $proxy_url ) {
|
||||
if ($proxy_url) {
|
||||
my $pgtIou =
|
||||
$xml->{'cas:authenticationSuccess'}->{'cas:proxyGrantingTicket'};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user