php処理cas認証の使用

4246 ワード

最近、プロジェクトはプラットフォームに埋め込まれてアプリケーションを作り、データのドッキングはms-security(前のブログを参照)、ログインはcas認証を使用し、今日は完全なコードを入れて、いくつかの回り道をしました.
コードの主なロジックは、ユーザーがアプリケーションにアクセスすると、アプリケーションがログインしたかどうかを検出し、ログインしていない場合はローカルurlを持ってcasログインセンターにジャンプし、ユーザーがユーザー名、パスワードを入力した後、正しい場合はticketを持って最初のバンドのurl(通常はこのアプリケーションのログインインタフェース)にジャンプし、ticketを検出した後にfile_を使用することである.get_contentsメソッドはcas認証のページを読み出し、希望するユーザー名を取得し、そのユーザー名を使用してアプリケーションのユーザーテーブルにレコードセッションを検索してログインします.
// cas       
$loginServer = "http://cas/sso/login";

// cas       
$validateServer = "http://cas/sso/serviceValidate";

// cas       
$address = "http://app/exam/";

//       ,  url    
if (isset($_REQUEST["redirectUrl"]) && !empty($_REQUEST["redirectUrl"])) {
    $address .= "?redirectUrl=" . $_REQUEST["redirectUrl"];
}

//       ticket
if (isset($_REQUEST["ticket"]) && !empty($_REQUEST["ticket"])) {
    try {

        // url   ticket cas      
        $validateurl = $validateServer . "?ticket=" . $_REQUEST["ticket"] . "&service=" . $address;
        header("Content-Type:text/html;charset=utf-8");

        //         
        $validateResult = str_replace('cas:', '', file_get_contents($validateurl));
        $validateXML = simplexml_load_string($validateResult);
        $successnode = $validateXML->authenticationSuccess[0];

        //     
        if (!empty($successnode)) {

            //      ,               
            $account = (string)$successnode->user;
            $auth = M('Auth')->where(array('a_account' => $account))->field('a_id, s_id, a_account')->find();

            //   session
            setPassportId($auth['a_id']);

            //        
            $info['a_id'] = $auth['a_id'];
            $info['a_last_login_time'] = time();
            $info['a_last_login_ip'] = ip2long(get_client_ip());
            $info['a_login_count'] = array('exp', 'a_login_count+1');
            M('Auth')->save($info);

            //        
            $map = array();
            $map['l_year'] = date('Y', time());
            $map['l_month'] = date('m', time());
            $map['a_id'] = $auth['a_id'];
            $map['s_id'] = $auth['s_id'];
            $l_id = M('Login')->where($map)->getField('l_id');

            if ($l_id) {
                $map['l_count'] = array('exp', 'l_count+1');
                M('Login')->where(array('l_id' => $l_id))->save($map);
            } else {
                $map['l_count'] = 1;
                M('Login')->add($map);
            }

            redirect(__APP__ . '/Index');

            //      , ticket  、    service,     
        } else {
            header("Location: " . $loginServer . "?service=" . $address);
            exit;
        }
    } catch (Exception $e) {
        echo "   ";
        echo $e->getMessage();
    }

    //     cas    
} else {
    header("Location: " . $loginServer . "?service=" . $address);
    exit;
}

ここで出会った問題の一つは、認証で返されたcas関連xmlがネーミングスペースを持っていることであり、最初は(コードにstr_replaceが使われていない)どうしても解析できなかったが、その後フォーラムに行って聞いてみると、自分でxml関連情報を探して、最後にstr_replaceは名前空間(namespace)を取り除いた後に解析は正常で、そこでフォーラムに行って友達が解答することを見てみて、問題を開けた後に、2人の壇主が意見を言ったことを発見して、その中のくどくど言うのは大いに経験豊富で、正確に答えを出して、しかし最も下のあれは私の機の上で解析していません
$str = <<<EOT
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
    <cas:authenticationSuccess>
        <cas:user>zhangjian</cas:user>
        <cas:language></cas:language>
    </cas:authenticationSuccess>
</cas:serviceResponse>
EOT;
  
  
 
$validateXML = simplexml_load_string($str, null, 0, 'cas', true);
print_r($validateXML);
 
$successnode = $validateXML->authenticationSuccess[0];
print_r($successnode);
 
//            
$xml = new DOMDocument();
$xml -> loadXML($str);
print_r($xml);