Laravel 5에서 OpenAM SAML 인증 지원
아래 샘플을 만들 때 리포지토리를 github에서 공개하고 있습니다.
→ htps : // 기주 b. 코 m / 타츠야 우에다 / ぁらゔぇl ML2_ mp ぇ
이미지의 크기가 너무 큰 것은 마음이 바뀌면 수정합니다.
라라벨 환경 준비
Laravel 프로젝트 만들기
composer create-project laravel/laravel LaravelSAML2 --prefer-dist
프로젝트 디렉토리로 이동
cd LaravelSAML2
SAML2 모듈 추가
composer require aacotroneo/laravel-saml2
Laravel에서 인증 사용
php artisan make:auth
.env 파일을 편집하여 데이터베이스에 연결할 수 있도록 합니다.
MySQL의 경우는 이런 느낌
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=foobar
DB_USERNAME=foobar
DB_PASSWORD=foobar
인증 관계 테이블을 마이그레이션
php artisan migrate
여기에서 동작 확인용 사용자를 등록하고 해당 사용자로 로그인할 수 있는지 확인합니다.
설정 파일 편집
config/app.php
'providers' => [
...
Aacotroneo\Saml2\Saml2ServiceProvider::class,
]
'alias' => [
...
'Saml2' => Aacotroneo\Saml2\Facades\Saml2Auth::class,
]
config/saml2_settings.php
아래 명령은 템플릿을 자동으로 생성합니다.php artisan vendor:publish
entityId는 OpenAM과 일치해야 합니다.
(다른 경우 Laravel 로그에서 Saml2 error ["invalid_response"]가 출력됩니다.)
<?php
return $settings = array( 'useRoutes' => true,
'routesPrefix' => '/saml2',
'routesMiddleware' => ['saml'],
'retrieveParametersFromServer' => false,
'logoutRoute' => '/logout',
'loginRoute' => '/home',
'errorRoute' => '/error',
'strict' => true, //@todo: make this depend on laravel config
'debug' => true, //@todo: make this depend on laravel config
'sp' => array(
'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
'x509cert' => 'foobar',
'privateKey' => 'foobar',
),
'idp' => array(
'entityId' => 'https://openam.example.com/OpenAM',
'singleSignOnService' => array(
'url' => 'https://openam.example.com/OpenAM/SSORedirect/metaAlias/idp',
),
'singleLogoutService' => array(
'url' => 'https://openam.example.com/OpenAM/IDPSloRedirect/metaAlias/idp',
),
'certFingerprint' => 'foobar',
),
'security' => array(
'nameIdEncrypted' => false,
'authnRequestsSigned' => true,
'logoutRequestSigned' => false,
'logoutResponseSigned' => false,
'signMetadata' => false,
'wantMessagesSigned' => false,
'wantAssertionsSigned' => false,
'wantNameIdEncrypted' => false,
'requestedAuthnContext' => true,
),
);
app/Http/Kernel.php
protected $middlewareGroups = [
...
'saml' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
app/Providers/EventServiceProvider.php
use App\User;
public function boot() {
....
Event::listen('Aacotroneo\Saml2\Events\Saml2LoginEvent', function ($event) {
$user = $event->getSaml2User();
$userData = [
'id' => $user->getUserId(),
'attributes' => $user->getAttributes(),
'assertion' => $user->getRawSamlAssertion()
];
$laravelUser = User::where('email', $user->getUserId())
->first();
Auth::login($laravelUser);
});
Event::listen('Aacotroneo\Saml2\Events\Saml2LogoutEvent', function ($event) {
//Auth::logout();
//Session::save();
});
}
동작 확인
/saml2/login에 액세스하면 SAML에서 인증을 수행하고 인증이 성공하면/home으로, 실패하면/error로 리디렉션됩니다.
로그인 페이지 등에이 URL에 대한 링크를 만드는 것이 편리하다고 생각합니다.
OpenAM 설정
다음 작업은 이미 트러스트 서클이 생성된 상태에서 진행됩니다.
엔티티 만들기
OpenAM 관리 화면에 로그인하고 Federation을 클릭합니다.
엔티티 공급자에서 엔티티 가져오기를 클릭합니다.
메타데이터 파일의 위치를 URL 또는 파일로 지정하고 [확인]을 클릭합니다.
웹 브라우저에서/saml2/metadata에 액세스할 때 표시되는 내용이 메타데이터가 됩니다.
이미 만든 트러스트 서클의 이름을 클릭합니다. 아래의 경우 "SimpleSAML"입니다.
「엔티티 프로바이더」의 「선택 가능」에 상기에서 임포트한 엔티티 프로바이더가 등록되어 있으므로,
그것을 선택하고 추가를 클릭합니다. 그런 다음 오른쪽 상단의 확인을 클릭합니다.
여기까지의 작업으로 OpenAM측의 설정이 완료됩니다.
laravel-saml2 0.11계에서 2.10계로 버전 업한다
laravel-saml2가 SAML 라이브러리로 이용하고 있는 onelogin/php-saml은 2.0계까지 php-mcrypt에 의존하고 있습니다.
php-mcrypt는 PHP 7.1.0에서 더 이상 사용되지 않으며 PHP 7.2.0에서 폐기되었습니다.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=foobar
DB_USERNAME=foobar
DB_PASSWORD=foobar
'providers' => [
...
Aacotroneo\Saml2\Saml2ServiceProvider::class,
]
'alias' => [
...
'Saml2' => Aacotroneo\Saml2\Facades\Saml2Auth::class,
]
<?php
return $settings = array( 'useRoutes' => true,
'routesPrefix' => '/saml2',
'routesMiddleware' => ['saml'],
'retrieveParametersFromServer' => false,
'logoutRoute' => '/logout',
'loginRoute' => '/home',
'errorRoute' => '/error',
'strict' => true, //@todo: make this depend on laravel config
'debug' => true, //@todo: make this depend on laravel config
'sp' => array(
'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
'x509cert' => 'foobar',
'privateKey' => 'foobar',
),
'idp' => array(
'entityId' => 'https://openam.example.com/OpenAM',
'singleSignOnService' => array(
'url' => 'https://openam.example.com/OpenAM/SSORedirect/metaAlias/idp',
),
'singleLogoutService' => array(
'url' => 'https://openam.example.com/OpenAM/IDPSloRedirect/metaAlias/idp',
),
'certFingerprint' => 'foobar',
),
'security' => array(
'nameIdEncrypted' => false,
'authnRequestsSigned' => true,
'logoutRequestSigned' => false,
'logoutResponseSigned' => false,
'signMetadata' => false,
'wantMessagesSigned' => false,
'wantAssertionsSigned' => false,
'wantNameIdEncrypted' => false,
'requestedAuthnContext' => true,
),
);
protected $middlewareGroups = [
...
'saml' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
use App\User;
public function boot() {
....
Event::listen('Aacotroneo\Saml2\Events\Saml2LoginEvent', function ($event) {
$user = $event->getSaml2User();
$userData = [
'id' => $user->getUserId(),
'attributes' => $user->getAttributes(),
'assertion' => $user->getRawSamlAssertion()
];
$laravelUser = User::where('email', $user->getUserId())
->first();
Auth::login($laravelUser);
});
Event::listen('Aacotroneo\Saml2\Events\Saml2LogoutEvent', function ($event) {
//Auth::logout();
//Session::save();
});
}
다음 작업은 이미 트러스트 서클이 생성된 상태에서 진행됩니다.
엔티티 만들기
OpenAM 관리 화면에 로그인하고 Federation을 클릭합니다.
엔티티 공급자에서 엔티티 가져오기를 클릭합니다.
메타데이터 파일의 위치를 URL 또는 파일로 지정하고 [확인]을 클릭합니다.
웹 브라우저에서/saml2/metadata에 액세스할 때 표시되는 내용이 메타데이터가 됩니다.
이미 만든 트러스트 서클의 이름을 클릭합니다. 아래의 경우 "SimpleSAML"입니다.
「엔티티 프로바이더」의 「선택 가능」에 상기에서 임포트한 엔티티 프로바이더가 등록되어 있으므로,
그것을 선택하고 추가를 클릭합니다. 그런 다음 오른쪽 상단의 확인을 클릭합니다.
여기까지의 작업으로 OpenAM측의 설정이 완료됩니다.
laravel-saml2 0.11계에서 2.10계로 버전 업한다
laravel-saml2가 SAML 라이브러리로 이용하고 있는 onelogin/php-saml은 2.0계까지 php-mcrypt에 의존하고 있습니다.
php-mcrypt는 PHP 7.1.0에서 더 이상 사용되지 않으며 PHP 7.2.0에서 폐기되었습니다.
대단한 변경은 아니지만 laravel-saml2 2.0 계에서는 여러 IDP에 대응한 관계로 설정 파일의 구성이 변경되어 있기 때문에 버전 업시의 memo입니다.
laravel-saml2 버전 업
composer.json
"require": {
"aacotroneo/laravel-saml2": "^2.0",
}
# composer php update aacotroneo/laravel-saml2
설정 파일 업데이트
config/saml2_settings.php
idpNames 연관 배열을 추가하고 strict/debug/sp/idp/security를 똑같이 제거
삭제한 부분은 다음 설정 파일로 이동합니다.
config/saml2_settings.php
// ADD
// laravel-saml2 2.0系から複数のIDPを設定出来るようになったため、その識別子
'idpNames' => ['kcprd'],
// DELETE
'strict' => true, //@todo: make this depend on laravel config
'debug' => env('APP_DEBUG'),
'sp' => array(
....
),
'idp' => array(
....
),
'security' => array(
....
),
config/saml2/kcprd_idp_settings.php
파일 이름 kcprd는 saml2_settings.php에 설정된 idpNames와 일치합니다.
$this_idp_env_id 는 환경 변수로부터 파라미터를 정의할 때의 식별자로, idpNames와 맞추는 것이 좋은가라고 생각합니다.
기본적으로 Onelogin saml 파일은 그대로 둡니다.
$settings의 내용은 saml2_settings.php로 삭제한 부분을 그대로 넣으면 괜찮다고 생각합니다.
config/saml2/kcprd_idp_settings.php
<?php
// If you choose to use ENV vars to define these values, give this IdP its own env var names
// so you can define different values for each IdP, all starting with 'SAML2_'.$this_idp_env_id
$this_idp_env_id = 'KCPRD';
//This is variable is for simplesaml example only.
// For real IdP, you must set the url values in the 'idp' config to conform to the IdP's real urls.
return $settings = array(
/*****
* One Login Settings
*/
'debug' => env('APP_DEBUG', false),
'sp' => array(
'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
'x509cert' => env('SAML2_'.$this_idp_env_id.'_SP_x509',''),
'privateKey' => env('SAML2_'.$this_idp_env_id.'_SP_PRIVATEKEY',''),
'entityId' => env('SAML2_'.$this_idp_env_id.'_SP_ENTITYID',''),
'assertionConsumerService' => array(
'url' => '',
),
'singleLogoutService' => array(
'url' => '',
),
),
'idp' => array(
'entityId' => env('SAML2_'.$this_idp_env_id.'_IDP_ENTITYID', $idp_host . '/saml2/idp/metadata.php'),
'singleSignOnService' => array(
'url' => env('SAML2_'.$this_idp_env_id.'_IDP_SSO_URL', $idp_host . '/saml2/idp/SSOService.php'),
),
'singleLogoutService' => array(
'url' => env('SAML2_'.$this_idp_env_id.'_IDP_SL_URL', $idp_host . '/saml2/idp/SingleLogoutService.php'),
),
'x509cert' => env('SAML2_'.$this_idp_env_id.'_IDP_x509', ''),
/*
* Instead of use the whole x509cert you can use a fingerprint
* (openssl x509 -noout -fingerprint -in "idp.crt" to generate it)
*/
),
/***
* OneLogin advanced settings
*/
'security' => array(
'nameIdEncrypted' => false,
'authnRequestsSigned' => false,
'logoutRequestSigned' => false,
'logoutResponseSigned' => false,
'signMetadata' => false,
'wantMessagesSigned' => false,
'wantAssertionsSigned' => false,
'wantNameIdEncrypted' => false,
'requestedAuthnContext' => true,
),
'contactPerson' => array(
'technical' => array(
'givenName' => 'name',
'emailAddress' => '[email protected]'
),
'support' => array(
'givenName' => 'Support',
'emailAddress' => '[email protected]'
),
),
'organization' => array(
'en-US' => array(
'name' => 'Name',
'displayname' => 'Display Name',
),
),
'wantAssertionsSigned' => true,
'wantNameIdEncrypted' => false,
);
SAML2 로그인 시 URL
지금까지는/saml2/login 이었지만/saml2/[idpName]/login 입니다.
위의 구성 파일은/saml2/kcprd/login입니다.
Reference
이 문제에 관하여(Laravel 5에서 OpenAM SAML 인증 지원), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/tatsuya_info/items/51b6af5ce9159234d1df텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)