CodeIgniter API对接ANAFA OAuth2.0遇访问策略拒绝及挂起问题
排查CodeIgniter对接ANAFA OAuth2.0时F5访问策略拒绝问题
问题概述
Postman中发起的请求完全正常,回调URL错误时会收到明确提示,但在CodeIgniter项目对接ANAFA的OAuth2.0时,请求挂起并返回F5 NETWORK访问策略拒绝(会话参考号:e2c6b34d)。
对接要求
- 类型:OAuth 2.0
- 授权数据位置:请求头
- 授权类型:Authorization Code
- 授权URL:
https://logincert.anaf.ro/anaf-oauth2/v1/authorize - 令牌撤销URL:
https://logincert.anaf.ro/anaf-oauth2/v1/revoke - 客户端认证:以Basic Auth头发送
原控制器代码
<?php class Etransport extends MY_Controller { public function __construct() { parent::__construct(); $this->load->library('httpclient'); } public function index() { $this->data['page_title'] = $this->lang->line('add_etransport'); $this->page_construct('settings/etransport', $this->data); } public function getAnafToken() { $clientId = 'xxx'; $clientSecret = 'fxxx'; $oauthUrl = 'https://logincert.anaf.ro/anaf-oauthv2/v1/authorize'; $redirectUrl = base_url('etransport/callback'); $redirectUrl .= '?clientId=' . urlencode($clientId); $redirectUrl .= '&clientSecret=' . urlencode($clientSecret); redirect("$oauthUrl?client_id=$clientId&response_type=code&redirect_uri=$redirectUrl"); } public function callback() { $code = $this->input->get('code'); $clientId = 'xxx'; $clientSecret = 'xxxx'; $tokenEndpoint = 'https://logincert.anaf.ro/anaf-oauthv2/v1/token'; $headers = array( 'Authorization' => 'Basic ' . base64_encode("$clientId:$clientSecret"), 'Content-type' => 'application/x-www-form-urlencoded' ); $body = http_build_query(array( 'grant_type' => 'authorization_code', 'code' => $code, 'redirect_uri' => base_url('etransport/callback') )); $this->load->library('httpclient'); $response = $this->httpclient->post($tokenEndpoint, $body, $headers); $accessToken = json_decode($response)->access_token; $this->load->model('Settings_model'); $this->Settings_model->save_access_token($accessToken); $data['access_token'] = $accessToken; $this->load->view('etransport', $data); } }
排查步骤与修复方案
1. 修正授权URL拼写错误
原代码中授权URL写为https://logincert.anaf.ro/anaf-oauthv2/v1/authorize,但对接要求的正确地址是https://logincert.anaf.ro/anaf-oauth2/v1/authorize(注意oauth2的位置,原代码误写为oauthv2)。URL错误会导致请求到非预期地址,触发F5的访问策略拦截。
2. 移除回调URL中的敏感参数
getAnafToken方法中,将clientId和clientSecret拼接到回调URL参数中的操作违反OAuth2.0规范,且敏感信息暴露在URL中会被F5的安全策略拦截。回调URL必须是预先在ANAFA后台配置的固定地址,不能动态添加参数。
修正后的getAnafToken方法:
public function getAnafToken() { $clientId = 'xxx'; $clientSecret = 'fxxx'; // 修正授权URL拼写 $oauthUrl = 'https://logincert.anaf.ro/anaf-oauth2/v1/authorize'; // 使用纯净的回调URL,与ANAFA后台配置一致 $redirectUrl = base_url('etransport/callback'); redirect("$oauthUrl?client_id=$clientId&response_type=code&redirect_uri=" . urlencode($redirectUrl)); }
3. 更换为原生CURL实现(解决重定向与请求规范问题)
第三方httpclient库可能存在配置缺陷,导致请求不符合F5的安全策略。改用原生CURL实现token请求,确保重定向、SSL验证、请求头配置正确:
修正后的callback方法:
public function callback() { $code = $this->input->get('code'); $clientId = 'xxx'; $clientSecret = 'xxxx'; // 修正令牌端点URL拼写 $tokenEndpoint = 'https://logincert.anaf.ro/anaf-oauth2/v1/token'; $redirectUrl = base_url('etransport/callback'); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $tokenEndpoint); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 启用SSL验证(生产环境必须开启) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 设置请求头 $headers = array( 'Authorization: Basic ' . base64_encode("$clientId:$clientSecret"), 'Content-Type: application/x-www-form-urlencoded' ); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // 设置请求体 $postData = http_build_query(array( 'grant_type' => 'authorization_code', 'code' => $code, 'redirect_uri' => $redirectUrl )); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); // 允许自动重定向(处理ANAFA可能的内部重定向) curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 5); // 设置超时时间,避免请求挂起 curl_setopt($ch, CURLOPT_TIMEOUT, 30); $response = curl_exec($ch); $error = curl_error($ch); curl_close($ch); if ($error) { // 输出CURL错误信息便于排查 die('CURL Error: ' . $error); } $responseData = json_decode($response, true); if (isset($responseData['access_token'])) { $accessToken = $responseData['access_token']; $this->load->model('Settings_model'); $this->Settings_model->save_access_token($accessToken); $data['access_token'] = $accessToken; $this->load->view('etransport', $data); } else { // 输出错误响应便于排查 die('Token获取失败: ' . $response); } }
4. 排查F5拦截的其他可能原因
- 服务器IP白名单:确认CodeIgniter部署的服务器IP已添加到ANAFA的信任IP列表中(Postman使用本地IP,可能已被允许)。
- 请求头规范:确保所有请求头符合ANAFA要求,避免自定义或不规范的请求头。
- 请求频率:检查是否因频繁请求触发F5的限流策略。
- SSL证书:确认服务器的SSL证书有效且被ANAFA信任(生产环境需使用正规CA签发的证书)。
内容的提问来源于stack exchange,提问作者Andreiaşi Marian
相关产品推荐
相关产品推荐

