Skip to content

Commit

Permalink
Day21-1
Browse files Browse the repository at this point in the history
  • Loading branch information
MilesChou committed Oct 5, 2022
1 parent 0b17037 commit 40f07bc
Show file tree
Hide file tree
Showing 12 changed files with 378 additions and 4 deletions.
40 changes: 39 additions & 1 deletion Makefile
Expand Up @@ -16,7 +16,33 @@ setup:
--response-types "code,token,id_token,token code,code id_token,id_token token,id_token token code" \
--scope openid \
--token-endpoint-auth-method client_secret_basic \
--callbacks http://127.0.0.1:8000/callback
--callbacks http://127.0.0.1:8000/callback \
--post-logout-callbacks "http://127.0.0.1:8000/logout/callback"
hydra --endpoint http://127.0.0.1:4445/ clients --skip-tls-verify \
create \
--id rp1 \
--secret secret1 \
--grant-types authorization_code,implicit,client_credentials,refresh_token \
--response-types "code,token,id_token,token code,code id_token,id_token token,id_token token code" \
--scope openid \
--token-endpoint-auth-method client_secret_basic \
--callbacks http://127.0.0.1:8000/rp1/callback \
--post-logout-callbacks "http://127.0.0.1:8000/rp1/logout/callback"
hydra --endpoint http://127.0.0.1:4445/ clients --skip-tls-verify \
create \
--id rp2 \
--secret secret2 \
--grant-types authorization_code,implicit,client_credentials,refresh_token \
--response-types "code,token,id_token,token code,code id_token,id_token token,id_token token code" \
--scope openid \
--token-endpoint-auth-method client_secret_basic \
--callbacks http://127.0.0.1:8000/rp2/callback \
--post-logout-callbacks "http://127.0.0.1:8000/rp2/logout/callback"

teardown:
hydra --endpoint http://127.0.0.1:4445/ clients delete my-rp
hydra --endpoint http://127.0.0.1:4445/ clients delete rp1
hydra --endpoint http://127.0.0.1:4445/ clients delete rp2

open:
open "http://127.0.0.1:8000/"
Expand All @@ -26,3 +52,15 @@ login:

logout:
open "http://127.0.0.1:8000/logout"

login-rp1:
open "http://127.0.0.1:8000/rp1/login"

logout-rp1:
open "http://127.0.0.1:8000/rp1/logout"

login-rp2:
open "http://127.0.0.1:8000/rp2/login"

logout-rp2:
open "http://127.0.0.1:8000/rp2/logout"
20 changes: 20 additions & 0 deletions app/Http/Controllers/Hydra/ConsentProvider.php
Expand Up @@ -4,7 +4,9 @@

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redirect;
use Ory\Hydra\Client\Api\AdminApi;
use Ory\Hydra\Client\Model\AcceptConsentRequest;
use RuntimeException;

class ConsentProvider
Expand All @@ -21,6 +23,24 @@ public function __invoke(Request $request, AdminApi $adminApi)

Log::debug('Get consent Request', json_decode((string)$consentRequest, true));

if ($consentRequest->getSkip()) {
Log::debug('Skip Login Provider');

$acceptConsentRequest = new AcceptConsentRequest([
'grantScope' => $consentRequest->getRequestedScope(),
]);

try {
$completedRequest = $adminApi->acceptConsentRequest($consentChallenge, $acceptConsentRequest);
} catch (\Throwable $e) {
throw new RuntimeException('Hydra Server error: ' . $e->getMessage());
}

Log::debug('Consent Completed Request', json_decode((string)$completedRequest, true));

return Redirect::away($completedRequest->getRedirectTo());
}

return view('auth.consent', [
'challenge' => $consentChallenge,
'scopes' => $consentRequest->getRequestedScope(),
Expand Down
20 changes: 20 additions & 0 deletions app/Http/Controllers/Hydra/LoginProvider.php
Expand Up @@ -4,7 +4,9 @@

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redirect;
use Ory\Hydra\Client\Api\AdminApi;
use Ory\Hydra\Client\Model\AcceptLoginRequest;
use RuntimeException;
use Throwable;

Expand All @@ -26,6 +28,24 @@ public function __invoke(Request $request, AdminApi $adminApi)

Log::debug('Login Request', json_decode((string)$loginRequest, true));

if ($loginRequest->getSkip()) {
Log::debug('Skip Login Provider');

$acceptLoginRequest = new AcceptLoginRequest([
'subject' => $loginRequest->getSubject(),
]);

try {
$completedRequest = $adminApi->acceptLoginRequest($loginChallenge, $acceptLoginRequest);
} catch (\Throwable $e) {
throw new RuntimeException('Hydra Server error: ' . $e->getMessage());
}

Log::debug('Completed Request: ', json_decode((string)$completedRequest, true));

return Redirect::away($completedRequest->getRedirectTo());
}

return view('auth.login', [
'challenge' => $loginChallenge,
]);
Expand Down
74 changes: 74 additions & 0 deletions app/Http/Controllers/Rp1/Callback.php
@@ -0,0 +1,74 @@
<?php

namespace App\Http\Controllers\Rp1;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Jose\Component\Checker\ClaimCheckerManagerFactory;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\JWSLoader;
use Ory\Hydra\Client\Api\AdminApi;
use Ory\Hydra\Client\Api\PublicApi;

class Callback
{
public function __invoke(
Request $request,
PublicApi $public,
JWK $jwk,
JWSLoader $loader,
ClaimCheckerManagerFactory $claimCheckerManagerFactory,
) {
$error = $request->input('error');

if (null !== $error) {
return match ($error) {
'access_denied' => response('使用者拒絕授權'),
default => response('未知的 error: ' . $error),
};
}

$redirectUri = 'http://127.0.0.1:8000/rp1/callback';

$public->getConfig()
->setUsername('rp1')
->setPassword('secret1');

try {
$tokenResponse = $public->oauth2Token(
grantType: 'authorization_code',
code: $request->input('code'),
redirectUri: $redirectUri
);
} catch (\Throwable $e) {
dump($e);
return response('請求 Token 失敗');
}

Log::debug('Token Response: ', json_decode((string)$tokenResponse, true));

dump(json_decode((string)$tokenResponse, true));

$userinfoEndpoint = $public->getConfig()->getHost() . '/userinfo';

$userInfo = Http::withToken($tokenResponse->getAccessToken())
->get($userinfoEndpoint);

Log::debug('User info: ', $userInfo->json());

$idToken = $tokenResponse->getIdToken();

$jws = $loader->loadAndVerifyWithKey($idToken, $jwk, $signature);

$claimCheckerManager = $claimCheckerManagerFactory->create(['exp', 'iat', 'iss']);

$claimCheckerManager->check(json_decode($jws->getPayload(), true));

dump(json_decode($jws->getPayload(), true));

$request->session()->put('rp1.id_token', $idToken);

return response('拿到身分驗證回應了');
}
}
30 changes: 30 additions & 0 deletions app/Http/Controllers/Rp1/Login.php
@@ -0,0 +1,30 @@
<?php

namespace App\Http\Controllers\Rp1;

use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redirect;

class Login
{
public function __invoke(): RedirectResponse
{
$authorizeUri = 'http://127.0.0.1:4444/oauth2/auth';

$query = Arr::query([
'client_id' => 'rp1',
'redirect_uri' => 'http://127.0.0.1:8000/rp1/callback',
'scope' => 'openid',
'response_type' => 'code',
'state' => '1a2b3c4d',
]);

$authenticationRequest = $authorizeUri . '?' . $query;

Log::info('Authentication Request: ' . $authenticationRequest);

return Redirect::away($authenticationRequest);
}
}
36 changes: 36 additions & 0 deletions app/Http/Controllers/Rp1/Logout.php
@@ -0,0 +1,36 @@
<?php

namespace App\Http\Controllers\Rp1;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redirect;

class Logout
{
public function __invoke(Request $request): RedirectResponse
{
$idToken = $request->session()->get('rp1.id_token');

if (null === $idToken) {
throw new \RuntimeException('No login session');
}

$query = Arr::query([
'client_id' => 'rp1',
'id_token_hint' => $idToken,
'post_logout_redirect_uri' => 'http://127.0.0.1:8000/rp1/logout/callback',
'state' => '1a2b3c4d',
]);

$endSessionEndpoint = 'http://127.0.0.1:4444/oauth2/sessions/logout';

$LogoutRequest = $endSessionEndpoint . '?' . $query;

Log::info('End session request: ' . $LogoutRequest);

return Redirect::away($LogoutRequest);
}
}
74 changes: 74 additions & 0 deletions app/Http/Controllers/Rp2/Callback.php
@@ -0,0 +1,74 @@
<?php

namespace App\Http\Controllers\Rp2;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Jose\Component\Checker\ClaimCheckerManagerFactory;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\JWSLoader;
use Ory\Hydra\Client\Api\AdminApi;
use Ory\Hydra\Client\Api\PublicApi;

class Callback
{
public function __invoke(
Request $request,
PublicApi $hydra,
JWK $jwk,
JWSLoader $loader,
ClaimCheckerManagerFactory $claimCheckerManagerFactory,
) {
$error = $request->input('error');

if (null !== $error) {
return match ($error) {
'access_denied' => response('使用者拒絕授權'),
default => response('未知的 error: ' . $error),
};
}

$redirectUri = 'http://127.0.0.1:8000/rp2/callback';

$hydra->getConfig()
->setUsername('rp2')
->setPassword('secret2');

try {
$tokenResponse = $hydra->oauth2Token(
grantType: 'authorization_code',
code: $request->input('code'),
redirectUri: $redirectUri
);
} catch (\Throwable $e) {
dump($e);
return response('請求 Token 失敗');
}

Log::debug('Token Response: ', json_decode((string)$tokenResponse, true));

dump(json_decode((string)$tokenResponse, true));

$userinfoEndpoint = $hydra->getConfig()->getHost() . '/userinfo';

$userInfo = Http::withToken($tokenResponse->getAccessToken())
->get($userinfoEndpoint);

Log::debug('User info: ', $userInfo->json());

$idToken = $tokenResponse->getIdToken();

$jws = $loader->loadAndVerifyWithKey($idToken, $jwk, $signature);

$claimCheckerManager = $claimCheckerManagerFactory->create(['exp', 'iat', 'iss']);

$claimCheckerManager->check(json_decode($jws->getPayload(), true));

dump(json_decode($jws->getPayload(), true));

$request->session()->put('rp2.id_token', $idToken);

return response('拿到身分驗證回應了');
}
}
30 changes: 30 additions & 0 deletions app/Http/Controllers/Rp2/Login.php
@@ -0,0 +1,30 @@
<?php

namespace App\Http\Controllers\Rp2;

use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redirect;

class Login
{
public function __invoke(): RedirectResponse
{
$authorizeUri = 'http://127.0.0.1:4444/oauth2/auth';

$query = Arr::query([
'client_id' => 'rp2',
'redirect_uri' => 'http://127.0.0.1:8000/rp2/callback',
'scope' => 'openid',
'response_type' => 'code',
'state' => '1a2b3c4d',
]);

$authenticationRequest = $authorizeUri . '?' . $query;

Log::info('Authentication Request: ' . $authenticationRequest);

return Redirect::away($authenticationRequest);
}
}

0 comments on commit 40f07bc

Please sign in to comment.