Changeset 3775


Ignore:
Timestamp:
09/04/08 09:45:36 (11 years ago)
Author:
pjkersha
Message:

Working Perl NDG Single Sign On client.

Location:
TI12-security/trunk/perl
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/perl/NDG/Security/Client.pm

    r3774 r3775  
    11#!/usr/bin/env perl 
    2 package ndgsecurity::ssoclient; 
    3  
    4 use Inline Python => <<'END'; 
    5 import base64 
    6 def urlSafeB64Encode(str): 
    7     return base64.urlsafe_b64encode(str) 
    8    
    9 from paste.registry import RegistryManager, StackedObjectProxy 
    10 session = StackedObjectProxy() 
    11  
    12 from ndg.security.common.pylons.security_util import setSecuritySession 
    13 def pySetSecuritySession(h, sid, u, org, rolesStr): 
    14     roles = rolesStr.split('r') 
    15     setSecuritySession(h=h, sid=sid, u=u, org=org, roles=roles) 
    16 END 
     2use strict; 
     3package NDG::Security::Client; 
    174 
    185use Storable qw(freeze thaw); 
    196use Crypt::CBC; 
    20 use CGI; 
     7use URI::Escape; 
     8use CGI qw/-debug/; 
     9use Log::Log4perl; 
     10 
     11Log::Log4perl::init('/var/www/cgi-bin/NDG/Security/ndg-security-log.cfg'); 
     12 
     13my $log = Log::Log4perl->get_logger; 
     14 
     15my %SECURITY_ARG = ('h'=>1, 'roles'=>1, 'sid'=>1, 'org'=>1, 'u'=>1); 
     16 
    2117 
    2218sub new  
    2319{ 
    2420    # Constructor 
    25     my $type = shift; 
     21    my $class = shift; 
    2622    my $cgi = shift; 
    2723    my $encryptionKey = "123456789"; 
    2824    my $self = { 
    29     "cgi"  => undef, 
    30     "encyptionKey" => $encryptionKey, 
    31     "cipher" => undef, 
    32     "cookieName" => "ndg-security", 
     25        "cgi"  => undef, 
     26        "encyptionKey" => $encryptionKey, 
     27        "cipher" => undef, 
     28        "cookieName" => "ndg-security", 
     29        "wayfURI" => "https://localhost/sso/wayf", 
     30        "b64encReturnToURL" => undef, 
    3331    }; 
    3432 
    35     bless $self; 
     33    bless($self, $class); 
    3634 
     35    # CGI object for convenient access to http environment 
     36    $self->{cgi} = $cgi or CGI->new(); 
     37 
     38    # Cipher for encryption of session cookie 
    3739    $self->{cipher} = new Crypt::CBC(-key=>$encryptionKey); 
    38     $self->{cgi} = $cgi or CGI->new(); 
     40     
     41    # Supply encoded form of return to URL ready to be passed to SSO Service for user login 
     42    $self->{b64encReturnToURL} = ''; 
     43     
    3944    return $self; 
    4045} 
    4146 
    42 sub sessionHandler 
     47 
     48sub ssoHandler 
    4349{ 
    4450    my $self = shift; 
     51     
     52    my $virtualHostName = $self->{cgi}->virtual_host(); 
     53    my $urlPath = $self->{cgi}->url(-absolute=>1); 
     54         
    4555    if ($self->{cgi}->param('h')) 
    4656    { 
    47         my $cookie = self->setSession(); 
    48         my $returnTo =  
    49             "http://" . $self->{cgi}->virtual_host() . $self->{cgi}->url(-absolute=>1); 
    50         $self->{cgi}->redirect(-uri=>$returnTo, -cookie=>$cookie, -nph=>1); 
     57        # 'h' argument is present in query indicating a GET call from a Single Sign On 
     58        # Service in response to a login 
     59         
     60        # Set a cookie based on the query args supplied from the SSO Service response 
     61        my $cookie = $self->_setSessionFromSSOResp(); 
     62         
     63        # Create query string with security args filtered out 
     64        my $query = $self->_stripSecurityQueryArgs(); 
     65         
     66        my $returnToURL = "http://" . $virtualHostName . $urlPath . $query; 
     67             
     68        $log->info("Generating redirection header for redirect to ".$returnToURL."..."); 
     69 
     70        # nph flag crashes with Apache - intended for MS IIS? 
     71        return $self->{cgi}->redirect(-uri=>$returnToURL, -cookie=>$cookie); 
     72    } 
     73    else 
     74    { 
     75        # No Call to the Single Sign On Service has been made - prepare return to URL  
     76        # for such a call - encode it ready to be incorporated into a login request to # the Single Sign On Service 
     77        # 
     78        # URL is set to https to ensure encrypted channel for SSO service -> to THIS  
     79        # SSO client transfer 
     80        my $queryStr = $self->{cgi}->query_string(); 
     81        my $returnToURL = "https://" . $virtualHostName . $urlPath ."?" . $queryStr; 
     82         
     83        $log->info("Generating return to URL with SSL transport ".$returnToURL."..."); 
     84         
     85        $self->{b64encReturnToURL} = urlSafeB64Encode($returnToURL); 
     86        return ''; 
    5187    } 
    5288} 
    5389 
    5490 
    55 sub makeCookie 
     91sub _stripSecurityQueryArgs 
     92{ 
     93    my $self = shift; 
     94    my %arg = $self->{cgi}->Vars; 
     95    my $queryStr = '?'; 
     96    my $key; 
     97    my $val; 
     98     
     99    # Iterate through the keys adding to the query string only if they are non-security 
     100    # related and they are a genuine URL parameter 
     101    while (($key, $val) = each %arg) 
     102    { 
     103        if (! $SECURITY_ARG{$key})# && $self->{cgi}->url_param($key)) 
     104        { 
     105            $queryStr .= uri_escape($key)."=".uri_escape($val)."&"; 
     106        } 
     107    } 
     108    # Remove trailing '&' (or '?' if no args set) 
     109    $queryStr = substr($queryStr, 0, -1); 
     110    return $queryStr; 
     111} 
     112 
     113 
     114sub _makeCookie 
    56115{ 
    57116    my $self = shift; 
     
    61120    my $encrSess = $self->{cipher}->encrypt_hex($serializedSess); 
    62121    my $cookie = $self->{cgi}->cookie( 
    63     #new CGI::Cookie( 
    64             -name=>$self->{cookieName}, 
    65             -value=>$encrSess, 
    66             -path=>'/', 
    67             -expires=>'+8h' 
    68             ); 
    69              
     122        -name=>$self->{cookieName}, 
     123        -value=>$encrSess, 
     124        -path=>'/', 
     125        -expires=>'+8h' 
     126        ); 
     127 
    70128    return $cookie; 
    71129} 
    72130 
    73131 
    74 sub getCookie 
     132sub _getCookie 
    75133{ 
    76134    my $self = shift; 
     
    78136    my $cookie = $self->{cgi}->cookie($self->{cookieName}); 
    79137    my $serialisedSess = $self->{cipher}->decrypt_hex($cookie); 
    80     my %session = thaw($serializedSess); 
     138    my %session = thaw($serialisedSess); 
    81139    return %session; 
    82140} 
    83141  
    84142  
    85 sub setSession 
     143# Parse query response from SSO Service and set a security session cookie 
     144sub _setSessionFromSSOResp 
    86145{ 
    87146    my $self = shift; 
     
    98157        roles => @roles); 
    99158         
    100     return $self->makeCookie(%session); 
     159    return $self->_makeCookie(%session); 
    101160} 
    102161 
    103 1;    # ensure good finish 
     162 
     163use Inline Python => <<'END'; 
     164import base64 
     165def urlSafeB64Encode(str): 
     166    return base64.urlsafe_b64encode(str) 
     167END 
     168 
     1691; 
    104170__END__ 
    105171 
  • TI12-security/trunk/perl/ndglogin.pl

    r3771 r3775  
    44use warnings; 
    55use CGI; 
    6 #use MIME::Base64::URLSafe; 
    7 use ndgsecurity::ssoclient qw (urlSafeB64Encode); 
    8   
     6#use ndgsecurity::ssoclient; 
     7use NDG::Security::Client; 
     8 
    99my $cgi = CGI->new(); 
    1010#my $session = ndgsecurity::ssoclient->new($cgi); 
    11 my $session = eval {new ndgsecurity::ssoclient($cgi)}; 
     11my $session = eval {new NDG::Security::Client($cgi)}; 
    1212 
    13 $session->sessionHandler(); 
    14 my $wayfURI = "https://localhost/sso/wayf"; 
    15  
    16 # Refer back to THIS URL but over https rather than http 
    17 my $returnTo = "https://" . $cgi->virtual_host() . $cgi->url(-absolute=>1); 
    18 my $b64encReturnTo = "";#urlSafeB64Encode($returnTo); 
    19  
    20 print $cgi->header('text/html'); 
    21 print $cgi->start_html('NDG Login'), 
    22 $cgi->h1('NDG Login'), 
    23 $returnTo, $cgi->br, 
    24 $cgi->start_form(-action=>$wayfURI), 
    25 $cgi->hidden('r', $b64encReturnTo), $cgi->br, 
    26 $cgi->submit('NDG Login'), 
    27 $cgi->end_form, $cgi->p, 
    28 $cgi->hr; 
    29  
    30 print $cgi->end_html; 
    31  
     13# Call Single Sign On handler 
     14my $redirectHdr = $session->ssoHandler(); 
     15if ($redirectHdr) 
     16{ 
     17    # A redirect header has created indicating the handler has received a response from 
     18    # a Single Sign Service 
     19    print $redirectHdr; 
     20} 
     21else 
     22{ 
     23    # Create a form based on the WAYF address and encoded return to address formulated by 
     24    # ssoHandler 
     25    print $cgi->header('text/html'); 
     26    print $cgi->start_html('NDG Login'), 
     27    $cgi->h1('NDG Login'), 
     28    $cgi->start_form(-action=>$session->{wayfURI}), 
     29    $cgi->hidden('r', $session->{b64encReturnToURL}), $cgi->br, 
     30    $cgi->submit('NDG Login'), 
     31    $cgi->end_form, $cgi->p, 
     32    $cgi->hr; 
    3233     
     34    print $cgi->end_html; 
     35} 
     36     
Note: See TracChangeset for help on using the changeset viewer.