2012年1月1日日曜日

シボレス対応サービス・サンプル

IDPはいいとして、SPっていらねー!ってことで、
(IDP側に消費者URLの登録が必要です)

<?

//IDPのURL
$dsturl='http://**********:8080/idp/profile/SAML2/Redirect/SSO';
//IDP側のメタデータに登録されているエントリID。①
$issuer='http://**********/shibsp';
//結果のPOST先(このPHP)。①の配下に「AssertionConsumerService」として登録されている。
$acsurl='http://**********/shibsp/shibsp.php';
//①の個人鍵。
$seckey =<<<KEY
-----BEGIN RSA PRIVATE KEY-----
**************************************************************
**************************************************************
**************************************************************
-----END RSA PRIVATE KEY-----
KEY;

//IDPから結果が渡された場合、、、
if ($s = $_POST[SAMLResponse]) {
    //暗号化されている部分を取り出す。
    preg_match_all('/<xenc:CipherValue>(.*?)</s',base64_decode($s),$_);
    list($comkey,$data) = array_map('base64_decode',$_[1]);
    
    //①の個人鍵で共通鍵を復元。
    $seckey = openssl_get_privatekey($seckey);
    openssl_private_decrypt($comkey,$comkey,$seckey,OPENSSL_PKCS1_OAEP_PADDING);
    
    //共通鍵でデータを復元。
    $mod = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'',MCRYPT_MODE_CBC,'');
    $len = mcrypt_enc_get_iv_size($mod);
    mcrypt_generic_init($mod,$comkey,substr($data,0,$len));
    $data = mdecrypt_generic($mod,substr($data,$len));
    
    //データから属性の値を取り出す。
    preg_match_all(
        '/<saml2:Attribute.*?FriendlyName="(.*?)".*?<saml2:AttributeValue.*?>(.*?)</s',
        $data,$all,PREG_SET_ORDER
    );
    $ret = array();
    foreach ($all as $_) {
        $ret[$_[1]]=urldecode($_[2]);
    }
    //属性を表示してみる。
    die(print_r($ret,1));
}

//未認証の場合、、、
$issue=gmdate('Y-m-d').'T'.gmdate('H:i:s').'Z'; //日付
$reqid=md5(time().exec('echo $$')); //ユニークID

//要求データ
$req =<<<REQ
<samlp:AuthnRequest
 xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
 ID="{$reqid}" IssueInstant="{$issue}" Version="2.0"
 ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
 AssertionConsumerServiceURL="{$acsurl}">
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">{$issuer}</saml:Issuer>
</samlp:AuthnRequest>
REQ;

//要求データをエンコード。
$req = urlencode(base64_encode(gzdeflate($req)));

//IDPへリダイレクト。
header('Location: '.$dsturl.'?SAMLRequest='.$req);

?>