无法使用 phpCas 和 Yii 重定向到 CAS 登录
Unable To Redirect To CAS Login with phpCas and Yii
我已经为此苦苦思索了一段时间,但似乎无法正常工作。当我调用 "phpCas::forceAuthentication" 时,我不断收到以下错误。
"No 'Access-Control-Allow-Origin' header..."。我添加了以下 header 但它仍然不起作用:
header('Access-Control-Allow-Origin: https://localhost');
在我的后端中,我通过以下方式包含 CAS:
require_once Yii::app()->basePath.'/lib/CAS.php';
这产生了一个错误,我解决了从(〜第 81 行)更改 CAS 文件夹中的 "Autoload.php":
spl_autoload_register('CAS_autoload');
到
spl_autoload_register('CAS_autoload',true ,true);
它解决了这个问题。因此,在所有这些背景下,这里是我尝试用来登录 CAS 的代码:
require_once Yii::app()->basePath.'/lib/CAS.php';
...
...
public function actionLogin() {
phpCAS::setNoCasServerValidation(); //don't verify SSL (testing)
$url = Yii::app()->params['casReturnURL'];
phpCAS::setFixedServiceURL ($url); //redirect from cas to this url
phpCAS::forceAuthentication(); //authenticate user
$this->actionIsLoggedInFetch(); //check login status
}
function actionIsLoggedInFetch(){
phpCAS::setNoCasServerValidation(); //don't validate SSL (testing)
$url = Yii::app()->params['casReturnURL']; //return url from CAS
phpCAS::setFixedServiceURL ($url); //set return url
$auth = phpCAS::checkAuthentication(); // check CAS authentication
if ($auth == true) {
$_SESSION['LOGGEDIN'] = true;
$_SESSION['USER'] = phpCas::getUser(); //get currently authenticate user
$return['LOGGEDIN'] = true;
}
else {
$_SESSION['LOGGEDIN'] = false;
$return['LOGGEDIN'] = false;
$_SESSION['USER'] = 'invalid';
}
echo jsonEncodePlusYii($return);
}
public function actionLogout() {
valRequestMethodGet();
phpCAS::setNoCasServerValidation(); //don't verify SSL
$url = Yii::app()->params['casReturnURL'];
phpCAS::logoutWithRedirectService($url); //logout then redirect to url
}
此代码产生上述错误。因此,我还使用 CAS 文件夹附带的 "example_gateway.php" 进行了测试,效果非常好。我还复制了它生成的 url ,当我将它粘贴到浏览器中时,它会让我很好地进入 CAS。它也 returns 我到正确的页面。这基本上就是该代码,但 php 文件中没有随附的 HTML。我在这里做错了什么? Yii 会改变 headers 来阻止这个调用吗?在这方面的任何帮助都会非常有帮助。
更新:进一步测试后,这仍然是断断续续的。如果我使用:
window.location.href = "/path/to/my/login/function";
它会很好地重定向。此外,如果我设置自己的 xhr 请求,它有时会这样做。但是,当我调用我的注销功能时,我从不重定向……永远。怎么了?这是调试日志。
2C49 .START (2016-02-04 16:23:17) phpCAS-1.3.4 ****************[CAS.php:467]
2C49 .=> phpCAS::client('2.0', 'cas.byu.edu', 443, '/cas') [CasController.php:9]
2C49 .| => CAS_Client::__construct('2.0', false, 'cas.byu.edu', 443, '/cas', true) [CAS.php:359]
2C49 .| <= ''
2C49 .<= ''
2C49 .=> phpCAS::setNoCasServerValidation() [CasController.php:33]
2C49 .| You have configured no validation of the legitimacy of the cas server. This is not recommended for production use. [CAS.php:1617]
2C49 .<= ''
2C49 .=> phpCAS::setFixedServiceURL('https://localhost/welfareManager') [CasController.php:35]
2C49 .<= ''
2C49 .=> phpCAS::forceAuthentication() [CasController.php:36]
2C49 .| => CAS_Client::forceAuthentication() [CAS.php:1078]
2C49 .| | => CAS_Client::isAuthenticated() [Client.php:1249]
2C49 .| | | => CAS_Client::_wasPreviouslyAuthenticated() [Client.php:1362]
2C49 .| | | | no user found [Client.php:1604]
2C49 .| | | <= false
2C49 .| | | no ticket found [Client.php:1463]
2C49 .| | <= false
2C49 .| | => CAS_Client::redirectToCas(false) [Client.php:1258]
2C49 .| | | => CAS_Client::getServerLoginURL(false, false) [Client.php:1625]
2C49 .| | | | => CAS_Client::getURL() [Client.php:342]
2C49 .| | | | <= 'https://localhost/welfareManager'
2C49 .| | | <= 'https://cas.byu.edu/cas/login?service=https%3A%2F%2Flocalhost%2FwelfareManager'
2C49 .| | | Redirect to : https://cas.byu.edu/cas/login?service=https%3A%2F%2Flocalhost%2FwelfareManager [Client.php:1632]
2C49 .| | | exit()
2C49 .| | | -
2C49 .| | -
2C49 .|
如果我打开网络日志,我会看到以下内容:
它没有重定向我:( .
因此,经过一周左右的努力,我找到了适合我的方法。我确信必须有更好的方法来做到这一点,但是嘿,这行得通。
所以从这里安装最新版本的 phpCAS 后:https://developer.jasig.org/cas-clients/php/current/
我将 "CAS" 文件夹和 "CAS.php" 文件移动到我的后端代码中。
然后我生成了一个类似中间人的文件,代码如下:
<html>
<body>
CAS Services completed. Redirecting, please wait...
</body>
<script>
//-------------------- PHPCAS SECTION ----------------------------
<?php
require_once 'protected/lib/CAS.php';
phpCAS::client(CAS_VERSION_2_0, 'cas.byu.edu', 443, '/cas');
//--------------------------------------------------------------------------
phpCAS::setNoCasServerValidation();
$url = 'https://localhost/welfareManagerBackend/CASLogic.php'; //You will notice that I am redirecting back to myself. This is how we get this to work, so this was on purpose
phpCAS::setFixedServiceURL($url);
if (isset($_REQUEST['logout'])) {
echo "Logging Out.";
$_SESSION['AUTH'] = false;
$_SESSION['AUTH_USER'] = '';
//phpCAS::logout();
$url = "https://localhost/welfareManager/";
phpCAS::logoutWithRedirectServiceAndUrl($url,'');
}
else {
$auth = phpCAS::checkAuthentication();
if($auth == false) {
$_SESSION['AUTH'] = false;
$_SESSION['AUTH_USER'] = '';
phpCAS::forceAuthentication();
}
else {
$_SESSION['AUTH'] = true;
$_SESSION['AUTH_USER'] = phpCAS::getUser();
}
}
?>
//--------------- PAGE REDIRECTING SERVICES -----------------------------------
console.log('CAS Finished. Redirecting...');
var url = window.location.origin+window.location.pathname;
url = url.replace(window.location.pathname,'/welfareManager/');
window.location.href = url;
</script>
您会看到这是 JS、HTML 和 PHP 的混合体。我为什么要这样做!?我也不喜欢,但这很管用。我这样做是因为每次我尝试对调用 CAS 的函数进行 ajax 调用时,它都会吐出我在原始问题中提到的所有上述错误。要解决此问题,如果您有一个调用 CAS 并获取 CAS return 本身的 php 页面,它将每次都正常工作而不会出现那些可怕的错误。
然后,我设置自己的 php 会话变量,用于检查以确保在我的服务器上调用其他脚本之前我已通过身份验证。无论 CAS returns 如何,这个页面总是将我重定向回我的前端索引。它仅用于根据 return 从 CAS 编辑的内容设置会话变量。
然后像跳转到新页面一样调用上面的代码(我是用上面的代码"CASLogic.php"调用的):
attemptLogin:function(){
var url = window.location.origin+window.location.pathname+"../welfareManagerBackend/CASLogic.php";
console.log("Traveling To URL: "+url);
window.location.href = url;
},
userLogout:function(){
console.log("Logging Out");
var url = window.location.origin+window.location.pathname;
url = url.replace(window.location.pathname,'/welfareManagerBackend/CASLogic.php?logout');
window.location.href = url;
},
(我在前端使用聚合物)。这里最重要的部分是我通过以下方式调用我的 "CASLogic.php" 函数:
window.location.href=...
希望这个冗长的解释能帮助将来和我一样苦苦挣扎的人。
我已经为此苦苦思索了一段时间,但似乎无法正常工作。当我调用 "phpCas::forceAuthentication" 时,我不断收到以下错误。
"No 'Access-Control-Allow-Origin' header..."。我添加了以下 header 但它仍然不起作用:
header('Access-Control-Allow-Origin: https://localhost');
在我的后端中,我通过以下方式包含 CAS:
require_once Yii::app()->basePath.'/lib/CAS.php';
这产生了一个错误,我解决了从(〜第 81 行)更改 CAS 文件夹中的 "Autoload.php":
spl_autoload_register('CAS_autoload');
到
spl_autoload_register('CAS_autoload',true ,true);
它解决了这个问题。因此,在所有这些背景下,这里是我尝试用来登录 CAS 的代码:
require_once Yii::app()->basePath.'/lib/CAS.php';
...
...
public function actionLogin() {
phpCAS::setNoCasServerValidation(); //don't verify SSL (testing)
$url = Yii::app()->params['casReturnURL'];
phpCAS::setFixedServiceURL ($url); //redirect from cas to this url
phpCAS::forceAuthentication(); //authenticate user
$this->actionIsLoggedInFetch(); //check login status
}
function actionIsLoggedInFetch(){
phpCAS::setNoCasServerValidation(); //don't validate SSL (testing)
$url = Yii::app()->params['casReturnURL']; //return url from CAS
phpCAS::setFixedServiceURL ($url); //set return url
$auth = phpCAS::checkAuthentication(); // check CAS authentication
if ($auth == true) {
$_SESSION['LOGGEDIN'] = true;
$_SESSION['USER'] = phpCas::getUser(); //get currently authenticate user
$return['LOGGEDIN'] = true;
}
else {
$_SESSION['LOGGEDIN'] = false;
$return['LOGGEDIN'] = false;
$_SESSION['USER'] = 'invalid';
}
echo jsonEncodePlusYii($return);
}
public function actionLogout() {
valRequestMethodGet();
phpCAS::setNoCasServerValidation(); //don't verify SSL
$url = Yii::app()->params['casReturnURL'];
phpCAS::logoutWithRedirectService($url); //logout then redirect to url
}
此代码产生上述错误。因此,我还使用 CAS 文件夹附带的 "example_gateway.php" 进行了测试,效果非常好。我还复制了它生成的 url ,当我将它粘贴到浏览器中时,它会让我很好地进入 CAS。它也 returns 我到正确的页面。这基本上就是该代码,但 php 文件中没有随附的 HTML。我在这里做错了什么? Yii 会改变 headers 来阻止这个调用吗?在这方面的任何帮助都会非常有帮助。
更新:进一步测试后,这仍然是断断续续的。如果我使用:
window.location.href = "/path/to/my/login/function";
它会很好地重定向。此外,如果我设置自己的 xhr 请求,它有时会这样做。但是,当我调用我的注销功能时,我从不重定向……永远。怎么了?这是调试日志。
2C49 .START (2016-02-04 16:23:17) phpCAS-1.3.4 ****************[CAS.php:467]
2C49 .=> phpCAS::client('2.0', 'cas.byu.edu', 443, '/cas') [CasController.php:9]
2C49 .| => CAS_Client::__construct('2.0', false, 'cas.byu.edu', 443, '/cas', true) [CAS.php:359]
2C49 .| <= ''
2C49 .<= ''
2C49 .=> phpCAS::setNoCasServerValidation() [CasController.php:33]
2C49 .| You have configured no validation of the legitimacy of the cas server. This is not recommended for production use. [CAS.php:1617]
2C49 .<= ''
2C49 .=> phpCAS::setFixedServiceURL('https://localhost/welfareManager') [CasController.php:35]
2C49 .<= ''
2C49 .=> phpCAS::forceAuthentication() [CasController.php:36]
2C49 .| => CAS_Client::forceAuthentication() [CAS.php:1078]
2C49 .| | => CAS_Client::isAuthenticated() [Client.php:1249]
2C49 .| | | => CAS_Client::_wasPreviouslyAuthenticated() [Client.php:1362]
2C49 .| | | | no user found [Client.php:1604]
2C49 .| | | <= false
2C49 .| | | no ticket found [Client.php:1463]
2C49 .| | <= false
2C49 .| | => CAS_Client::redirectToCas(false) [Client.php:1258]
2C49 .| | | => CAS_Client::getServerLoginURL(false, false) [Client.php:1625]
2C49 .| | | | => CAS_Client::getURL() [Client.php:342]
2C49 .| | | | <= 'https://localhost/welfareManager'
2C49 .| | | <= 'https://cas.byu.edu/cas/login?service=https%3A%2F%2Flocalhost%2FwelfareManager'
2C49 .| | | Redirect to : https://cas.byu.edu/cas/login?service=https%3A%2F%2Flocalhost%2FwelfareManager [Client.php:1632]
2C49 .| | | exit()
2C49 .| | | -
2C49 .| | -
2C49 .|
如果我打开网络日志,我会看到以下内容:
它没有重定向我:( .
因此,经过一周左右的努力,我找到了适合我的方法。我确信必须有更好的方法来做到这一点,但是嘿,这行得通。
所以从这里安装最新版本的 phpCAS 后:https://developer.jasig.org/cas-clients/php/current/
我将 "CAS" 文件夹和 "CAS.php" 文件移动到我的后端代码中。
然后我生成了一个类似中间人的文件,代码如下:
<html>
<body>
CAS Services completed. Redirecting, please wait...
</body>
<script>
//-------------------- PHPCAS SECTION ----------------------------
<?php
require_once 'protected/lib/CAS.php';
phpCAS::client(CAS_VERSION_2_0, 'cas.byu.edu', 443, '/cas');
//--------------------------------------------------------------------------
phpCAS::setNoCasServerValidation();
$url = 'https://localhost/welfareManagerBackend/CASLogic.php'; //You will notice that I am redirecting back to myself. This is how we get this to work, so this was on purpose
phpCAS::setFixedServiceURL($url);
if (isset($_REQUEST['logout'])) {
echo "Logging Out.";
$_SESSION['AUTH'] = false;
$_SESSION['AUTH_USER'] = '';
//phpCAS::logout();
$url = "https://localhost/welfareManager/";
phpCAS::logoutWithRedirectServiceAndUrl($url,'');
}
else {
$auth = phpCAS::checkAuthentication();
if($auth == false) {
$_SESSION['AUTH'] = false;
$_SESSION['AUTH_USER'] = '';
phpCAS::forceAuthentication();
}
else {
$_SESSION['AUTH'] = true;
$_SESSION['AUTH_USER'] = phpCAS::getUser();
}
}
?>
//--------------- PAGE REDIRECTING SERVICES -----------------------------------
console.log('CAS Finished. Redirecting...');
var url = window.location.origin+window.location.pathname;
url = url.replace(window.location.pathname,'/welfareManager/');
window.location.href = url;
</script>
您会看到这是 JS、HTML 和 PHP 的混合体。我为什么要这样做!?我也不喜欢,但这很管用。我这样做是因为每次我尝试对调用 CAS 的函数进行 ajax 调用时,它都会吐出我在原始问题中提到的所有上述错误。要解决此问题,如果您有一个调用 CAS 并获取 CAS return 本身的 php 页面,它将每次都正常工作而不会出现那些可怕的错误。 然后,我设置自己的 php 会话变量,用于检查以确保在我的服务器上调用其他脚本之前我已通过身份验证。无论 CAS returns 如何,这个页面总是将我重定向回我的前端索引。它仅用于根据 return 从 CAS 编辑的内容设置会话变量。
然后像跳转到新页面一样调用上面的代码(我是用上面的代码"CASLogic.php"调用的):
attemptLogin:function(){
var url = window.location.origin+window.location.pathname+"../welfareManagerBackend/CASLogic.php";
console.log("Traveling To URL: "+url);
window.location.href = url;
},
userLogout:function(){
console.log("Logging Out");
var url = window.location.origin+window.location.pathname;
url = url.replace(window.location.pathname,'/welfareManagerBackend/CASLogic.php?logout');
window.location.href = url;
},
(我在前端使用聚合物)。这里最重要的部分是我通过以下方式调用我的 "CASLogic.php" 函数:
window.location.href=...
希望这个冗长的解释能帮助将来和我一样苦苦挣扎的人。