#!/usr/bin/perl -w # Simple OpenID Connect client use strict; use JSON; use LWP::UserAgent; use MIME::Base64; use URI::Escape; use CGI; use Data::Dumper; #============================================================================== # Configuration #============================================================================== my $client_id = "lemonldap"; my $client_secret = "secret"; my $portal_url = "http://auth.example.com"; my $authorization_uri = "$portal_url/oauth2/authorize"; my $token_uri = "$portal_url/oauth2/token"; #============================================================================== # CSS #============================================================================== my $css = <url . "?openidconnectcallback=1"; # Start HTTP response print $cgi->header(); print "\n"; print "\n"; print "\n"; print "OpenID Connect sample client\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print "
\n"; print "
\n"; print "

OpenID Connect sample client

\n"; print "
\n"; # Check callback my $callback = $cgi->param("openidconnectcallback"); unless ($callback) { # AuthN Request my $response_type = uri_escape("code"); my $scope = uri_escape("openid profile email"); $client_id = uri_escape($client_id); $redirect_uri = uri_escape($redirect_uri); my $state = uri_escape("ABCDEFGHIJKLMNOPQRSTUVWXXZ"); my $redirect_url = $authorization_uri . "?response_type=$response_type&client_id=$client_id&scope=$scope&redirect_uri=$redirect_uri&state=$state"; print "

Login on $authorization_uri

\n"; print "
\n"; print "Authorization flow\n"; print "
\n"; } else { print "

Callback received

"; print "
\n"; print "
\n"; print "

OpenID Connect callback received

\n"; print "
\n"; print "
\n"; print "
"
      . $cgi->url( -path_info => 1, -query => 1 )
      . "
\n"; print "
\n"; print "
\n"; # AuthN Response my $state = $cgi->param("state"); my $code = $cgi->param("code"); # Check state unless ( $state eq "ABCDEFGHIJKLMNOPQRSTUVWXXZ" ) { print "
"; print "

OpenIDConnect callback state $state is invalid

"; print "
"; print "
"; print "
"; print $cgi->end_html(); exit 0; } my $grant_type = "authorization_code"; my %form; $form{"code"} = $code; $form{"client_id"} = $client_id; $form{"client_secret"} = $client_secret; $form{"redirect_uri"} = $redirect_uri; $form{"grant_type"} = $grant_type; my $response = $ua->post( $token_uri, \%form, "Content-Type" => 'application/x-www-form-urlencoded' ); if ( $response->is_error ) { print "
"; print "

Bad authorization response: " . $response->message . "

"; print "

$response->content

"; print "
"; print ""; print ""; print $cgi->end_html(); exit 0; } # Get access_token and id_token my $content = $response->decoded_content; my $json; eval { $json = decode_json $content; }; if ($@) { print "
"; print "

Wrong JSON content

"; print "
"; print ""; print ""; print $cgi->end_html(); exit 0; } if ( $json->{error} ) { print "
"; print "

Error in token response:" . $json->{error} . "

"; print "
"; print ""; print ""; print $cgi->end_html(); exit 0; } my $access_token = $json->{access_token}; my $id_token = $json->{id_token}; print "
\n"; print "
\n"; print "

Tokens

\n"; print "
\n"; print "
\n"; print "
Access token: $access_token
"; print "
ID token: $id_token
"; print "
\n"; print "
\n"; # Get ID token content my ( $id_token_header, $id_token_payload, $id_token_signature ) = split( /\./, $id_token ); # TODO check signature my $id_token_payload_hash = decode_json( decode_base64($id_token_payload) ); print "
\n"; print "
\n"; print "

ID Token content

\n"; print "
\n"; print "
\n"; print "
" . Dumper($id_token_payload_hash) . "
"; print "
\n"; print "
\n"; } print "\n"; print "\n"; print $cgi->end_html(); exit 0;