Module to manage SAML Common Domain Cookie (#18)

This commit is contained in:
Clément Oudot 2010-09-24 14:23:27 +00:00
parent e7fdfb79ed
commit c3e9fbba7e
4 changed files with 237 additions and 0 deletions

View File

@ -319,6 +319,7 @@ install_portal_site: install_conf_dir
@cp -pR --remove-destination ${SRCPORTALDIR}/example/error.pl ${RPORTALDIR}
@cp -pR --remove-destination ${SRCPORTALDIR}/example/mail.pl ${RPORTALDIR}
@cp -pR --remove-destination ${SRCPORTALDIR}/example/metadata.pl ${RPORTALDIR}
@cp -pR --remove-destination ${SRCPORTALDIR}/example/cdc.pl ${RPORTALDIR}
@cp -pR --remove-destination ${SRCPORTALDIR}/example/skins/* $(RPORTALSKINSDIR)
@if [ "$(PORTALDIR)/skins/" != "$(PORTALSKINSDIR)/" ]; then \
for skin in $$(ls lemonldap-ng-portal/example/skins/); do \
@ -567,6 +568,7 @@ debian-diff:
@$(DIFF) lemonldap-ng-portal/example/error.pl /var/lib/lemonldap-ng/portal/error.pl ||true
@$(DIFF) lemonldap-ng-portal/example/mail.pl /var/lib/lemonldap-ng/portal/mail.pl ||true
@$(DIFF) lemonldap-ng-portal/example/metadata.pl /var/lib/lemonldap-ng/portal/metadata.pl ||true
@$(DIFF) lemonldap-ng-portal/example/cdc.pl /var/lib/lemonldap-ng/portal/cdc.pl ||true
@# Handler
@$(DIFF) lemonldap-ng-handler/lib/Lemonldap/NG/Handler /usr/share/perl5/Lemonldap/NG/Handler ||true
@# Common
@ -593,6 +595,7 @@ default-diff:
@$(DIFF) lemonldap-ng-portal/example/error.pl $(LMPREFIX)/htdocs/portal/error.pl ||true
@$(DIFF) lemonldap-ng-portal/example/mail.pl $(LMPREFIX)/htdocs/portal/mail.pl ||true
@$(DIFF) lemonldap-ng-portal/example/metadata.pl $(LMPREFIX)/htdocs/portal/metadata.pl ||true
@$(DIFF) lemonldap-ng-portal/example/cdc.pl $(LMPREFIX)/htdocs/portal/cdc.pl ||true
@# Handler
@$(DIFF) lemonldap-ng-handler/lib/Lemonldap/NG/Handler /usr/local/share/perl/5.10.0/Lemonldap/NG/Handler ||true
@$(DIFF) lemonldap-ng-handler/example/MyHandler.pm $(LMPREFIX)/handler/MyHandler.pm ||true

View File

@ -34,6 +34,7 @@ example/AuthLA/tpl/themes/federid/page-bg.png
example/AuthLA/tpl/themes/federid/sso.css
example/AuthLA/tpl/themes/federid/wui.css
example/cas.pl
example/cdc.pl
example/error.pl
example/index.pl
example/index_simple.pl
@ -184,6 +185,7 @@ lib/Lemonldap/NG/Portal/AuthSAML.pm
lib/Lemonldap/NG/Portal/AuthSSL.pm
lib/Lemonldap/NG/Portal/AuthTwitter.pm
lib/Lemonldap/NG/Portal/CDA.pm
lib/Lemonldap/NG/Portal/CDC.pm
lib/Lemonldap/NG/Portal/IssuerDBCAS.pm
lib/Lemonldap/NG/Portal/IssuerDBNull.pm
lib/Lemonldap/NG/Portal/IssuerDBOpenID.pm

View File

@ -0,0 +1,31 @@
#!/usr/bin/perl
#==============================================================================
# Script to manage SAML Cross Domain Cookie
#
# Part of LemonLDAP::NG project
#==============================================================================
use strict;
use Lemonldap::NG::Portal::CDC;
# Create portal
my $portal = Lemonldap::NG::Portal::CDC->new();
# Process
my $result = $portal->process();
my $values = $portal->{cdc_values};
# Very simple page displaying cookie content
print $portal->header('text/html; charset=utf-8');
print $portal->start_html('Cross Domain Cookie');
print $portal->h1("Cross Domain Cookie");
if ( defined $values ) {
print $portal->p($_) foreach (@$values);
}
else {
print $portal->p("No cookie found");
}
print $portal->end_html();
exit;

View File

@ -0,0 +1,201 @@
## @file
# Module for SAML Common Domain Cookie Support
## @class Lemonldap::NG::Portal::CDC
# Class for SAML Common Domain Cookie Support
package Lemonldap::NG::Portal::CDC;
use strict;
use warnings;
use MIME::Base64;
use Lemonldap::NG::Portal::SharedConf; # inherits
use Lemonldap::NG::Portal::_SAML; # inherits
our $VERSION = '0.1';
our @ISA = qw(Lemonldap::NG::Portal::_SAML Lemonldap::NG::Portal::SharedConf);
## @method int process()
# Main method to process CDC requests
# @return portal error code
sub process {
my $self = shift;
my $cdc_idp = "";
my $cdc_cookie = "";
# Default values
my $cdc_name = $self->{samlCommonDomainCookieName} || '_saml_idp';
my $cdc_domain = $self->{samlCommonDomainCookieDomain} || $ENV{'HTTP_HOST'};
$self->lmLog( "[CDC] Cookie name: $cdc_name", 'debug' );
$self->lmLog( "[CDC] Domain name: $cdc_domain", 'debug' );
# Request parameter
my $action = $self->param('action') || ""; # What we do
my $idp = $self->param('idp'); # IDP ID in write mode
# Control URL
my $control_url = $self->_sub('controlUrlOrigin');
unless ( $control_url == PE_OK ) {
$self->lmLog( "[CDC] Bad URL", 'error' );
return $control_url;
}
# Get cookie
my %cookies = fetch CGI::Cookie;
$cdc_cookie = $cookies{$cdc_name} if %cookies;
$cdc_cookie &&= $cdc_cookie->value;
if ($cdc_cookie) {
$self->lmLog( "[CDC] Cookie found with value $cdc_cookie", 'debug' );
}
# Write request
# Called in an iFrame
# Get or build common domain cookie
# Append IDP to common domain cookie
if ( $action eq 'write' ) {
$self->lmLog( "[CDC] Write request detected", 'debug' );
# Check IDP value
unless ($idp) {
$self->lmLog( "[CDC] No IDP given", 'error' );
return PE_SAML_ERROR;
}
# Add IDP value
$self->lmLog( "[CDC] Will add IDP $idp to IDP list", 'debug' );
my $encoded_idp = encode_base64($idp);
# Remove IDP value if already present
$cdc_cookie =~ s/$encoded_idp(\s+)?//g;
# Add a space separator
$cdc_cookie .= ( $cdc_cookie ? " " : "" );
$cdc_cookie .= $encoded_idp;
$self->lmLog( "[CDC] Build cookie $cdc_name with value $cdc_cookie",
'debug' );
# Build cookie
push @{ $self->{cookie} }, $self->cookie(
-name => $cdc_name,
-value => $cdc_cookie,
-domain => $cdc_domain,
-path => "/", # See SAML protocol
-secure => 1, # See SAML protocol
-httponly => $self->{httpOnly},
-expires => $self->{cookieExpiration},
);
}
# Read request
# Get last IDP from domain cookie
# Return on SP with idp as parameter
elsif ( $action eq 'read' ) {
$self->lmLog( "[CDC] Read request detected", 'debug' );
# Get last IDP from cookie
if ($cdc_cookie) {
$cdc_idp = decode_base64( ( split /\s+/, $cdc_cookie )[-1] );
$self->lmLog( "[CDC] Get value $cdc_idp", 'debug' );
}
}
# Redirect if needed
if ( $self->{urldc} ) {
# Add CDC IDP in return URL if needed
$self->{urldc} .= (
$cdc_idp
? (
$self->{urldc} =~ /\?/
? '&idp=' . $cdc_idp
: '?idp=' . $cdc_idp
)
: ''
);
# Redirect
$self->_sub('autoRedirect');
}
if ($cdc_cookie) {
# Parse cookie to display it if not redirected
my @cdc_values =
map( decode_base64($_), ( split( /\s+/, $cdc_cookie ) ) );
$self->{cdc_values} = \@cdc_values;
}
return PE_OK;
}
1;
__END__
=head1 NAME
=encoding utf8
Lemonldap::NG::Portal::CDC - Manage SAML Common Domain Cookie
=head1 SYNOPSIS
use Lemonldap::NG::Portal::CDC;
my $portal = new Lemonldap::NG::Portal::CDC();
$portal->process();
# Write here HTML to manage errors and confirmation messages
=head1 DESCRIPTION
Lemonldap::NG::Portal::CDC - Manage SAML Common Domain Cookie
See L<Lemonldap::NG::Portal::SharedConf> for a complete example of use of
Lemonldap::Portal::* libraries.
=head1 METHODS
=head3 process
Main method.
=head1 SEE ALSO
L<Lemonldap::NG::Handler>, L<Lemonldap::NG::Portal::SharedConf>, L<CGI>,
http://wiki.lemonldap.objectweb.org/xwiki/bin/view/NG/Presentation
=head1 AUTHOR
Clement Oudot, E<lt>clement@oodo.netE<gt>
=head1 BUG REPORT
Use OW2 system to report bug or ask for features:
L<http://forge.objectweb.org/tracker/?group_id=274>
=head1 DOWNLOAD
Lemonldap::NG is available at
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2005-2009 by Xavier Guimard E<lt>x.guimard@free.frE<gt> and
Clement Oudot, E<lt>clement@oodo.netE<gt>
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.4 or,
at your option, any later version of Perl 5 you may have available.
=cut