Start of registration endpoint implementation (#184)

This commit is contained in:
Clément Oudot 2015-03-30 15:57:23 +00:00
parent b14ec43a88
commit 2e0f1b7088
5 changed files with 150 additions and 55 deletions

View File

@ -774,6 +774,13 @@ has 'oidcServiceMetaDataJWKSURI' => (
documentation => 'OpenID Connect JWKS endpoint',
);
has 'oidcServiceMetaDataRegistrationURI' => (
is => 'rw',
isa => 'Str',
default => 'register',
documentation => 'OpenID Connect registration endpoint',
);
has 'oidcServiceMetaDataTokenURI' => (
is => 'rw',
isa => 'Str',

View File

@ -316,9 +316,8 @@ sub cstruct {
%$h,
oidcRPMetaDataNode => {
$k2 => {
_nodes => [
qw(oidcRPMetaDataExportedVars oidcRPMetaDataOptions)
],
_nodes =>
[ qw(oidcRPMetaDataExportedVars oidcRPMetaDataOptions) ],
oidcRPMetaDataExportedVars => {
_nodes =>
["hash:/oidcRPMetaDataExportedVars/$k2:vars:btext"],
@ -328,24 +327,24 @@ sub cstruct {
_nodes => [
qw(oidcRPMetaDataOptionsAuthentication oidcRPMetaDataOptionsDisplay oidcRPMetaDataOptionsUserIDAttr oidcRPMetaDataOptionsIDTokenSignAlg oidcRPMetaDataOptionsIDTokenExpiration oidcRPMetaDataOptionsAccessTokenExpiration oidcRPMetaDataOptionsRedirectUris)
],
oidcRPMetaDataOptionsAuthentication => {
_nodes => [
qw(oidcRPMetaDataOptionsClientID oidcRPMetaDataOptionsClientSecret)
],
oidcRPMetaDataOptionsClientID =>
oidcRPMetaDataOptionsAuthentication => {
_nodes => [
qw(oidcRPMetaDataOptionsClientID oidcRPMetaDataOptionsClientSecret)
],
oidcRPMetaDataOptionsClientID =>
"text:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsClientID",
oidcRPMetaDataOptionsClientSecret =>
oidcRPMetaDataOptionsClientSecret =>
"password:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsClientSecret",
},
oidcRPMetaDataOptionsDisplay => {
_nodes => [
qw(oidcRPMetaDataOptionsDisplayName oidcRPMetaDataOptionsIcon)
],
oidcRPMetaDataOptionsDisplayName =>
},
oidcRPMetaDataOptionsDisplay => {
_nodes => [
qw(oidcRPMetaDataOptionsDisplayName oidcRPMetaDataOptionsIcon)
],
oidcRPMetaDataOptionsDisplayName =>
"text:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsDisplayName",
oidcRPMetaDataOptionsIcon =>
oidcRPMetaDataOptionsIcon =>
"text:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsIcon",
},
},
oidcRPMetaDataOptionsUserIDAttr =>
"text:/oidcRPMetaDataOptions/$k2/oidcRPMetaDataOptionsUserIDAttr",
oidcRPMetaDataOptionsIDTokenSignAlg =>
@ -1601,7 +1600,7 @@ sub struct {
oidcServiceMetaDataEndPoints => {
_nodes => [
qw(oidcServiceMetaDataAuthorizeURI oidcServiceMetaDataTokenURI oidcServiceMetaDataUserInfoURI oidcServiceMetaDataJWKSURI)
qw(oidcServiceMetaDataAuthorizeURI oidcServiceMetaDataTokenURI oidcServiceMetaDataUserInfoURI oidcServiceMetaDataJWKSURI oidcServiceMetaDataRegistrationURI)
],
oidcServiceMetaDataAuthorizeURI =>
@ -1612,6 +1611,8 @@ sub struct {
'text:/oidcServiceMetaDataUserInfoURI',
oidcServiceMetaDataJWKSURI =>
'text:/oidcServiceMetaDataJWKSURI',
oidcServiceMetaDataRegistrationURI =>
'text:/oidcServiceMetaDataRegistrationURI',
},
oidcServiceMetaDataSecurity => {

View File

@ -306,6 +306,7 @@ sub en {
oidcServiceMetaDataEndPoints => 'End points',
oidcServiceMetaDataIssuer => 'Issuer identifier',
oidcServiceMetaDataJWKSURI => 'JWKS',
oidcServiceMetaDataRegistrationURI => 'Registration',
oidcServiceMetaDataSecurity => 'Security',
oidcServiceMetaDataTokenURI => 'Token',
oidcServiceMetaDataUserInfoURI => 'User Info',
@ -864,41 +865,42 @@ sub fr {
"Expiration des jetons d'identité",
oidcRPMetaDataOptionsIDTokenSignAlg =>
"Algorithme de signature des jetons d'identité",
oidcRPMetaDataOptionsRedirectUris => 'Adresses de redirection',
oidcRPMetaDataOptionsUserIDAttr => "Attribut de l'identifiant",
oidcRPStateTimeout => 'Durée d\'une session state',
oidcServiceMetaData => "Service OpenID Connect",
oidcServiceMetaDataAuthorizeURI => "Autorisation",
oidcServiceMetaDataEndPoints => "Points d'accès",
oidcServiceMetaDataIssuer => "Identifiant du fournisseur",
oidcServiceMetaDataJWKSURI => 'JWKS',
oidcServiceMetaDataSecurity => 'Sécurité',
oidcServiceMetaDataTokenURI => "Jeton",
oidcServiceMetaDataUserInfoURI => 'Informations Utilisateur',
oidcServicePrivateKeySig => 'Clé privée de signature',
oidcServicePublicKeySig => 'Clé publique de signature',
openIdAttr => 'Identifiant OpenID',
openIdAuthnLevel => 'Niveau d\'authentification',
openIdExportedVars => 'Variables exportées',
openIdIDPList => 'Domaines autorisés',
openIdIssuerSecret => 'Jeton secret',
openIdParams => 'Paramètres OpenID',
openIdSecret => 'Jeton secret',
openIdSreg => 'Associations SREG',
openIdSreg_fullname => 'Nom complet',
openIdSreg_nickname => 'Surnom',
openIdSreg_language => 'Langage',
openIdSreg_postcode => 'Code postal',
openIdSreg_timezone => 'Zone horaire',
openIdSreg_country => 'Pays',
openIdSreg_gender => 'Genre',
openIdSreg_email => 'Email',
openIdSreg_dob => 'Date de naissance',
openIdSPList => 'Domaines autorisés',
passwordDB => 'Module de mot de passe',
passwordManagement => 'Gestion des mots de passe',
persistentSessions => 'Sessions persistantes',
persistentStorage => 'Module Apache::Session',
oidcRPMetaDataOptionsRedirectUris => 'Adresses de redirection',
oidcRPMetaDataOptionsUserIDAttr => "Attribut de l'identifiant",
oidcRPStateTimeout => 'Durée d\'une session state',
oidcServiceMetaData => "Service OpenID Connect",
oidcServiceMetaDataAuthorizeURI => "Autorisation",
oidcServiceMetaDataEndPoints => "Points d'accès",
oidcServiceMetaDataIssuer => "Identifiant du fournisseur",
oidcServiceMetaDataJWKSURI => 'JWKS',
oidcServiceMetaDataRegistrationURI => 'Enregistrement',
oidcServiceMetaDataSecurity => 'Sécurité',
oidcServiceMetaDataTokenURI => "Jeton",
oidcServiceMetaDataUserInfoURI => 'Informations Utilisateur',
oidcServicePrivateKeySig => 'Clé privée de signature',
oidcServicePublicKeySig => 'Clé publique de signature',
openIdAttr => 'Identifiant OpenID',
openIdAuthnLevel => 'Niveau d\'authentification',
openIdExportedVars => 'Variables exportées',
openIdIDPList => 'Domaines autorisés',
openIdIssuerSecret => 'Jeton secret',
openIdParams => 'Paramètres OpenID',
openIdSecret => 'Jeton secret',
openIdSreg => 'Associations SREG',
openIdSreg_fullname => 'Nom complet',
openIdSreg_nickname => 'Surnom',
openIdSreg_language => 'Langage',
openIdSreg_postcode => 'Code postal',
openIdSreg_timezone => 'Zone horaire',
openIdSreg_country => 'Pays',
openIdSreg_gender => 'Genre',
openIdSreg_email => 'Email',
openIdSreg_dob => 'Date de naissance',
openIdSPList => 'Domaines autorisés',
passwordDB => 'Module de mot de passe',
passwordManagement => 'Gestion des mots de passe',
persistentSessions => 'Sessions persistantes',
persistentStorage => 'Module Apache::Session',
persistentStorageOptions => 'Paramètres du module Apache::Session',
port => 'Port',
portal => 'URL',

View File

@ -11,6 +11,7 @@ my $authorize_uri = $portal->{oidcServiceMetaDataAuthorizeURI};
my $token_uri = $portal->{oidcServiceMetaDataTokenURI};
my $userinfo_uri = $portal->{oidcServiceMetaDataUserInfoURI};
my $jwks_uri = $portal->{oidcServiceMetaDataJWKSURI};
my $registration_uri = $portal->{oidcServiceMetaDataRegistrationURI};
my ($path) = ( $issuerDBOpenIDConnectPath =~ /(\w+)/ );
my $issuer = $portal->{oidcServiceMetaDataIssuer};
@ -23,8 +24,8 @@ $configuration->{authorization_endpoint} =
$configuration->{token_endpoint} = $issuer . $path . "/" . $token_uri;
$configuration->{userinfo_endpoint} = $issuer . $path . "/" . $userinfo_uri;
$configuration->{jwks_uri} = $issuer . $path . "/" . $jwks_uri;
# RECOMMENDED # $configuration->{registration_endpoint}
$configuration->{registration_endpoint} =
$issuer . $path . "/" . $registration_uri;
$configuration->{scopes_supported} = [qw/openid profile email address phone/];
$configuration->{response_types_supported} = [
"code",

View File

@ -7,6 +7,7 @@ package Lemonldap::NG::Portal::IssuerDBOpenIDConnect;
use strict;
use Lemonldap::NG::Portal::Simple;
use String::Random qw(random_string);
use base qw(Lemonldap::NG::Portal::_OpenIDConnect);
our $VERSION = '2.00';
@ -34,6 +35,7 @@ sub issuerForUnAuthUser {
my $token_uri = $self->{oidcServiceMetaDataTokenURI};
my $userinfo_uri = $self->{oidcServiceMetaDataUserInfoURI};
my $jwks_uri = $self->{oidcServiceMetaDataJWKSURI};
my $registration_uri = $self->{oidcServiceMetaDataRegistrationURI};
my $issuer = $self->{oidcServiceMetaDataIssuer};
# Called URL
@ -356,6 +358,71 @@ sub issuerForUnAuthUser {
}
# REGISTRATION
if ( $url_path =~ m#${issuerDBOpenIDConnectPath}${registration_uri}# ) {
$self->lmLog( "URL $url detected as an OpenID Connect REGISTRATION URL",
'debug' );
# TODO: check Initial Access Token
# Specific message to allow DOS detection
my $source_ip = $self->ipAddr;
$self->lmLog( "OpenID Connect Registration request from $source_ip",
'warn' );
# Get client metadata
my $client_metadata_json = $self->param('POSTDATA');
$self->lmLog( "Client metadata received: $client_metadata_json",
'debug' );
my $client_metadata = $self->decodeJSON($client_metadata_json);
my $registration_response = {};
# Check redirect_uris
unless ( $client_metadata->{redirect_uris} ) {
$self->lmLog( "Field redirect_uris is mandatory", 'error' );
$self->returnJSONError( 'invalid_client_metadata',
'Field redirect_uris is mandatory' );
$self->quit;
}
# RP identifier
my $registration_time = time;
my $rp = "register-$registration_time";
# Generate Client ID and Client Password
my $client_id = random_string("...............");
my $client_secret = random_string("...............");
# Register known parameters
my $client_name =
$client_metadata->{client_name} || "Self registered client";
my $logo_uri = $client_metadata->{logo_uri};
my $id_token_signed_response_alg =
$client_metadata->{id_token_signed_response_alg} || "RS256";
# TODO: register RP in global configuration
# Send registration response
$registration_response->{'client_id'} = $client_id;
$registration_response->{'client_secret'} = $client_secret;
$registration_response->{'client_id_issued_at'} = $registration_time;
$registration_response->{'client_id_expires_at'} = 0;
$registration_response->{'client_name'} = $client_name;
$registration_response->{'logo_uri'} = $logo_uri;
$registration_response->{'id_token_signed_response_alg'} =
$id_token_signed_response_alg;
# TODO: return 201 HTTP code
$self->returnJSON($registration_response);
$self->lmLog( "Registration response sent", 'debug' );
$self->quit;
}
PE_OK;
}
@ -371,6 +438,7 @@ sub issuerForAuthUser {
my $token_uri = $self->{issuerDBOpenIDConnectTokenURI};
my $userinfo_uri = $self->{issuerDBOpenIDConnectUserInfoURI};
my $jwks_uri = $self->{oidcServiceMetaDataJWKSURI};
my $registration_uri = $self->{oidcServiceMetaDataRegistrationURI};
my $issuer = $self->{oidcServiceMetaDataIssuer};
# Session ID
@ -989,6 +1057,22 @@ sub issuerForAuthUser {
$self->quit;
}
# REGISTRATION
if ( $url_path =~ m#${issuerDBOpenIDConnectPath}${registration_uri}# ) {
$self->lmLog( "URL $url detected as an OpenID Connect REGISTRATION URL",
'debug' );
# This should not happen
$self->lmLog(
"Registration request found on an active SSO session, ignoring it",
'error'
);
$self->returnJSONError("invalid_request");
$self->quit;
}
PE_OK;
}