Skeleton to manage different OIDC response types (#184)

This commit is contained in:
Clément Oudot 2015-03-16 17:00:56 +00:00
parent d3d282e7ba
commit 33bc52b619

View File

@ -288,7 +288,8 @@ sub issuerForAuthUser {
# Get and save parameters # Get and save parameters
my $oidc_request = {}; my $oidc_request = {};
foreach my $param (qw/response_type scope client_id state redirect_uri/) foreach
my $param (qw/response_type scope client_id state redirect_uri nonce/)
{ {
$oidc_request->{$param} = $self->getHiddenFormValue($param) $oidc_request->{$param} = $self->getHiddenFormValue($param)
|| $self->param($param); || $self->param($param);
@ -298,12 +299,33 @@ sub issuerForAuthUser {
$self->setHiddenFormValue( $param, $oidc_request->{$param} ); $self->setHiddenFormValue( $param, $oidc_request->{$param} );
} }
# TODO check all required parameters # Detect requested flow
# TODO validate parameters against OAuth 2.0 spec my $response_type = $oidc_request->{'response_type'};
# Authorization Code Flow my $response_types = {
if ( $oidc_request->{'response_type'} eq "code" ) { "code" => "authorizationcode",
$self->lmLog( "OIDC auhtorization code flow requested", 'debug' ); "id_token" => "implicit",
"id_token token" => "implicit",
"code id_token" => "hybrid",
"code token" => "hybrid",
"code id_token token" => "hybrid",
};
my $flow = $response_types->{$response_type};
unless ($flow) {
$self->lmLog( "Unknown response type: $response_type", 'error' );
return PE_ERROR;
}
$self->lmLog(
"OIDC $flow flow requested (response type: $response_type)",
'debug' );
# TODO check all required parameters
if ( $flow eq "implicit" and not defined $oidc_request->{'nonce'} ) {
$self->lmLog( "Nonce is required for implicit flow", 'error' );
return PE_ERROR;
}
# Check openid scope # Check openid scope
unless ( $oidc_request->{'scope'} =~ /\bopenid\b/ ) { unless ( $oidc_request->{'scope'} =~ /\bopenid\b/ ) {
@ -314,8 +336,7 @@ sub issuerForAuthUser {
} }
# Check client_id # Check client_id
$self->lmLog( $self->lmLog( "Request from client id " . $oidc_request->{'client_id'},
"Request from client id " . $oidc_request->{'client_id'},
'debug' ); 'debug' );
# Verify that client_id is registered in configuration # Verify that client_id is registered in configuration
@ -331,11 +352,8 @@ sub issuerForAuthUser {
} }
else { else {
$self->lmLog( $self->lmLog(
"Client id " "Client id " . $oidc_request->{'client_id'} . " match RP $rp",
. $oidc_request->{'client_id'} 'debug' );
. " match RP $rp",
'debug'
);
} }
# Obtain consent # Obtain consent
@ -344,8 +362,7 @@ sub issuerForAuthUser {
and $self->{sessionInfo}->{"_oidc_consent_scope_$rp"} ) and $self->{sessionInfo}->{"_oidc_consent_scope_$rp"} )
{ {
$ask_for_consent = 0; $ask_for_consent = 0;
my $consent_time = my $consent_time = $self->{sessionInfo}->{"_oidc_consent_time_$rp"};
$self->{sessionInfo}->{"_oidc_consent_time_$rp"};
my $consent_scope = my $consent_scope =
$self->{sessionInfo}->{"_oidc_consent_scope_$rp"}; $self->{sessionInfo}->{"_oidc_consent_scope_$rp"};
@ -355,8 +372,8 @@ sub issuerForAuthUser {
); );
# Check accepted scope # Check accepted scope
foreach my $requested_scope ( foreach
split( /\s+/, $oidc_request->{'scope'} ) ) my $requested_scope ( split( /\s+/, $oidc_request->{'scope'} ) )
{ {
if ( $consent_scope =~ /\b$requested_scope\b/ ) { if ( $consent_scope =~ /\b$requested_scope\b/ ) {
$self->lmLog( "Scope $requested_scope already accepted", $self->lmLog( "Scope $requested_scope already accepted",
@ -365,8 +382,7 @@ sub issuerForAuthUser {
else { else {
$self->lmLog( $self->lmLog(
"Scope $requested_scope was not previously accepted", "Scope $requested_scope was not previously accepted",
'debug' 'debug' );
);
$ask_for_consent = 1; $ask_for_consent = 1;
last; last;
} }
@ -378,12 +394,10 @@ sub issuerForAuthUser {
{ "_oidc_consent_time_$rp" => time } ); { "_oidc_consent_time_$rp" => time } );
$self->updatePersistentSession( $self->updatePersistentSession(
{ {
"_oidc_consent_scope_$rp" => "_oidc_consent_scope_$rp" => $oidc_request->{'scope'}
$oidc_request->{'scope'}
} }
); );
$self->lmLog( "Consent given for Relying Party $rp", $self->lmLog( "Consent given for Relying Party $rp", 'debug' );
'debug' );
} }
else { else {
$self->lmLog( "Obtain user consent for Relying Party $rp", $self->lmLog( "Obtain user consent for Relying Party $rp",
@ -405,8 +419,7 @@ sub issuerForAuthUser {
. '" />' ) . '" />' )
if $icon; if $icon;
$self->info( '<h3>' $self->info( '<h3>'
. sprintf( $self->msg(PM_OIDC_CONSENT), . sprintf( $self->msg(PM_OIDC_CONSENT), $display_name )
$display_name )
. '</h3>' ); . '</h3>' );
$self->info('<ul>'); $self->info('<ul>');
@ -438,6 +451,9 @@ sub issuerForAuthUser {
} }
} }
# Authorization Code Flow
if ( $flow eq "authorizationcode" ) {
# Generate code # Generate code
my $codeSession = $self->getOpenIDConnectSession(); my $codeSession = $self->getOpenIDConnectSession();
my $code = $codeSession->id(); my $code = $codeSession->id();
@ -465,6 +481,25 @@ sub issuerForAuthUser {
$self->_sub('autoRedirect'); $self->_sub('autoRedirect');
} }
# Implicit Flow
if ( $flow eq "implicit" ) {
#TODO
return PE_ERROR;
}
# Hybrid Flow
if ( $flow eq "hybrid" ) {
#TODO
return PE_ERROR;
}
$self->lmLog( "No flow has been selected", 'debug' );
return PE_OK;
} }
# TOKEN # TOKEN