流程
(1)、单点登陆需要在IRS上申请对应的组件(这里申请的是个人用户单点登录组件)
(2)、审核流程通过后做下面的操作 在irs上找到“我申请的组件” 一> 打开"获取资源"(如下图)
(3)、将相关信息发送给对应的联系人(这里其实就是让联系人配置你的回调地址)
格式如下 :
ak:填写如上图
sk:填写如上图
系统名称:填写如上图
测试地址:填写如上图(用来做跳转的回调地址页面)
正式地址:填写如上图(用来做跳转的回调地址页面)
(4)、阅读管理员提供的单点登录文档,找到登录流程,在登录流程下面有个票据认证
(5)、根据组件提供的url选择对应的网关进行设置(这里是方式2的登录网关)
(6)、直接锁定文档(如下图)
(7)、写代码 复制就能使用
注:博主这里的代码是个人用户单点登录组件!!!网关是方式2!!!(方式1的需要自行修改)
剩下的自行看代码
语言php
框架 tp5.1
封装的sso类 注意开始的6处需修改!!!
namespace app\hfive\controller;
use Carbon\Carbon;
use think\Controller;
class Sso extends Controller
{
//以下皆为组件申请后的获取 需修改!!! 自行填写
private $SecretKey = "需修改!!!";//SK
private $AccessKey = "需修改!!!";//AK
private $idValidation_url = "需修改!!!";//用户认证的互联网请求地址
private $ticketValidation_url = "需修改!!!";//票据认证的互联网请求地址
private $generateST_url = "需修改!!!";//根根据令牌获取第三方接入资源票据的互联网请求地址
private $getUserInfo_url = "需修改!!!";//根据令牌获取用户详细信息的互联网请求地址
private $get_time;//时间戳
private $sign;//签名
/**
* Sso constructor.
*/
public function __construct()
{
$this->get_time = date('Ymdhis');//时间戳 年月日时分秒 例:2009年10月10日 12时12分12秒格式为20091010121212;
$this->sign = md5($this->AccessKey . $this->SecretKey . $this->get_time);//MD5(sk+ak+time)
}
/**
* 用户认证
* @param string $loginname |登录用户名
* @param string $password |密码
* @return object
*/
function idValidation($loginname, $password)
{
$post_data = [//定义请求参数
"servicecode" => $this->AccessKey,//组件平台的AccessKey
'method' => "idValidation",
'time' => $this->get_time,
'sign' => $this->sign, //签名 MD5(sk+ak+time)
"loginname" => $loginname,//登录用户名
"encryptiontype" => "3",//1. 表示明文2. 表示Base64(UTF-8字符集操作) 3 .MD5 (标准32位小写)4 .AES (sun自带库加密,密钥为SSO提供)5. 3DES (sun自带库加密,密钥为SSO提供) 注:UTF-8字符集操作
"password" => $password,//密码
"datatype" => "json"
];
return $this->urlPost($this->idValidation_url, $post_data, $this->getHeader($this->generateHeader($this->idValidation_url, $this->AccessKey, $this->SecretKey, "POST")));//3发送表单请求 //2构造请求 //1获取请求头
}
/**
* 票据认证
* @param string $st |票据
* @return object
*/
function ticketValidation($st)
{
$post_data = [//定义请求参数
"servicecode" => $this->AccessKey,//组件平台的AccessKey
'method' => "ticketValidation",
'time' => $this->get_time,
'sign' => $this->sign,//签名 MD5(sk+ak+time)
"st" => $st,//票据
"datatype" => "json"
];
return $this->urlPost($this->ticketValidation_url, $post_data, $this->getHeader($this->generateHeader($this->ticketValidation_url, $this->AccessKey, $this->SecretKey, "POST")));//3发送表单请求 //2构造请求 //1获取请求头
}
/**
* 根据令牌获取第三方接入资源票据
* @param string token 令牌
* @return object
*/
function generateST($token)
{
$post_data = [//定义请求参数
"servicecode" => $this->AccessKey,//组件平台的AccessKey
'method' => "generateST",
'time' => $this->get_time,
'sign' => $this->sign,//签名 MD5(sk+ak+time)
"proxyapp" => $this->AccessKey,//被代理接入资源的AccessKey 被代理接入资源在SSO注册成功后的业务代码,由【SSO管理员】提供。
"token" => $token,//token
"datatype" => "json"
];
return $this->urlPost($this->generateST_url, $post_data, $this->getHeader($this->generateHeader($this->generateST_url, $this->AccessKey, $this->SecretKey, "POST")));//3发送表单请求 //2构造请求 //1获取请求头
}
/**
* 根据令牌获取用户详细信息
* @param string token 令牌
* @return object
*/
function getUserInfo($token)
{
$get_time = date('Ymdhis');//时间戳 年月日时分秒 例:2009年10月10日 12时12分12秒格式为20091010121212;
$post_data = [//定义请求参数
"servicecode" => $this->AccessKey,//组件平台的AccessKey
'method' => "getUserInfo",
'time' => $this->get_time,
'sign' => $this->sign,//签名 MD5(sk+ak+time)
"token" => $token,//令牌
"datatype" => "json"
];
return $this->urlPost($this->getUserInfo_url, $post_data, $this->getHeader($this->generateHeader($this->getUserInfo_url, $this->AccessKey, $this->SecretKey, "POST")));//3发送表单请求 //2构造请求 //1获取请求头
}
/**
* post请求
* @param $url url
* @param $post_data 表单数据
* @param $header 请求头
* @return false
*/
function urlPost($url, $post_data, $header)
{
$post_data = http_build_query($post_data);//将数组转化成key=value的格式
$ch = curl_init();//初始化cURL
curl_setopt($ch, CURLOPT_URL, $url);//抓取指定网页
// curl_setopt($ch, CURLINFO_HEADER_OUT, true); //打印请求头
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//要求结果为字符串并输出到屏幕上
curl_setopt($ch, CURLOPT_POST, true);//Post请求方式
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);//Post变量
$output = curl_exec($ch);//执行并获得HTML内容
$request_header = curl_getinfo($ch, CURLINFO_HEADER_OUT);
print_r($request_header);
curl_close($ch);//释放cURL句柄
$output = json_decode($output, true);
return ($output);
//如果请求要求 "datatype"=>"xml" 使用下面的解析xml数据 我这里用的是 "datatype"=>"json"
// // 使用domdocument 来操作xml
// $dom = new \DOMDocument();
// // 解析xml类
// $dom->loadXML($output);
// // 处理xml数据
// $zarr=$this->getArray($dom->documentElement);
// return $zarr;
}
/**
* 获取请求头
* @param $generateHeader 待处理的请求头
* @return string[]
*/
function getHeader($generateHeader)
{
$X_BG_HMAC_SIGNATURE = $generateHeader["X-BG-HMAC-SIGNATURE"];
$X_BG_HMAC_ACCESS_KEY = $generateHeader["X-BG-HMAC-ACCESS-KEY"];
$X_BG_HMAC_ALGORITHM = $generateHeader['X-BG-HMAC-ALGORITHM'];
$X_BG_DATE_TIME = $generateHeader['X-BG-DATE-TIME'];
return array('Content-Type: application/x-www-form-urlencoded', "X-BG-HMAC-SIGNATURE: $X_BG_HMAC_SIGNATURE",
"X-BG-HMAC-ALGORITHM: $X_BG_HMAC_ALGORITHM",
"X-BG-HMAC-ACCESS-KEY: $X_BG_HMAC_ACCESS_KEY",
"X-BG-DATE-TIME: $X_BG_DATE_TIME");
}
/**
* 处理xml数据
* @param $node 需要处理的xml数据
* @return false
*/
function getArray($node)
{
$array = false;
if ($node->hasAttributes()) {
foreach ($node->attributes as $attr) {
$array[$attr->nodeName] = $attr->nodeValue;
}
}
if ($node->hasChildNodes()) {
if ($node->childNodes->length == 1) {
$array[$node->firstChild->nodeName] = $this->getArray($node->firstChild);
} else {
foreach ($node->childNodes as $childNode) {
if ($childNode->nodeType != XML_TEXT_NODE) {
$array[$childNode->nodeName][] = $this->getArray($childNode);
}
}
}
} else {
return $node->nodeValue;
}
return $array;
}
/**
* 系统级请求参数。
* @param $method,比如:ticketValidation
* @param accessKey 应用的 AK
* @param secretKey 应用的 SK
* @return array
*/
function systemParams($method, $accessKey, $secretKey)
{
// 例如: Thu, 21 Apr 2022 05:36:06 GMT。这里生成时间需要根据自己框架调整。
// $now = \Carbon\Carbon::now()->tz(config('app.timezone'));//有Carbon插件的用这行 没有Carbon插件的用下面一行,不过需要替换一下时间
$now = $this->str(gmdate("l, d F Y H:i:s", time()) . " GMT"); //输出: Wednesday, 09 April 2014 03:53:36 GMT 替换成 Wed, 09 Apr 2014 03:53:36 GMT
echo $now;
$time = $now->format('YmdHis');
$sign = md5($accessKey . $secretKey . $time);
$data = [
'servicecode' => $accessKey,
'method' => $method,
'time' => $time,
'sign' => $sign,
'datatype' => 'json',
];
return $data;
}
/**
* 构造请求 header。
* @param $urlStr 请求url,全路径格式,比如:https://ibcdsg.zj.gov.cn:8443/restapi/prod/IC33000020220228000002/sso/servlet/simpleauth
* @param $requestMethod 请求方法,大写格式,如:GET, POST
* @param accessKey 应用的 AK
* @param secretKey 应用的 SK
* @return array
*/
function generateHeader($urlStr, $accessKey, $secretKey, $requestMethod = 'POST')
{
// 例如: Thu, 21 Apr 2022 05:36:06 GMT。这里生成时间需要根据自己框架调整。
// $dateTime = \Carbon\Carbon::now()->tz(config('app.timezone'))->toRfc7231String();//有Carbon插件的用这行 没有Carbon插件的用下面一行,不过需要替换一下时间
$dateTime = $this->str(gmdate("l, d F Y H:i:s", time()) . " GMT"); //输出: Wednesday, 09 April 2014 03:53:36 GMT 替换成 Wed, 09 Apr 2014 03:53:36 GMT
$uri = parse_url($urlStr);
$query = $uri['query'] ?? [];
$canonicalQueryString = $this->getCanonicalQueryString($query);
$message = strtoupper($requestMethod) . "\n" . $uri['path'] . "\n" . $canonicalQueryString . "\n" . $accessKey . "\n" . $dateTime . "\n";
$sign = hash_hmac('sha256', $message, $secretKey, true);
$sign = base64_encode($sign);
$header = [
'X-BG-HMAC-SIGNATURE' => $sign,
'X-BG-HMAC-ALGORITHM' => 'hmac-sha256',
'X-BG-HMAC-ACCESS-KEY' => $accessKey,
'X-BG-DATE-TIME' => $dateTime,
];
return $header;
}
/**
* 获取加密字符串。
* @param $query 比如:a=1&b=2&c=3
* @return string
*/
function getCanonicalQueryString($query)
{
if (!$query) {
return '';
}
parse_str($query, $output);
ksort($output);
$params = [];
foreach ($output as $k => $v) {
if (null !== $v) {
$k = urlencode($k);
$v = urlencode($v);
$params[] = $k . '=' . (string)$v;
}
}
$queryParamString = implode('&', $params);
return $queryParamString;
}
//替换
function str($date)
{
$date = str_ireplace("Monday", "Mon", $date);
$date = str_ireplace("Tuesday", "Tue", $date);
$date = str_ireplace("Wednesday", "Wed", $date);
$date = str_ireplace("Thursday", "Thu", $date);
$date = str_ireplace("Friday", "Fri", $date);
$date = str_ireplace("Saturday", "Sat", $date);
$date = str_ireplace("Sunday", "Sun", $date);
$date = str_ireplace("January", "Jan", $date);
$date = str_ireplace("February", "Feb", $date);
$date = str_ireplace("March", "Mar", $date);
$date = str_ireplace("April", "Apr", $date);
// str_ireplace("May","May", $date);//简写一样无需替换
$date = str_ireplace("June", "Jun", $date);
$date = str_ireplace("July", "Jul", $date);
$date = str_ireplace("August", "Aug", $date);
$date = str_ireplace("September", "Sep", $date);
$date = str_ireplace("October", "Oct", $date);
$date = str_ireplace("November", "Nov", $date);
$date = str_ireplace("December", "Dec", $date);
return $date;
}
}
demo类调用写个人业务
namespace app\hfive\controller;
use app\common\model\PioneerPersonal;
use Carbon\Carbon;
use think\Controller;
use think\Db;
class Demo extends Controller /*demo*/
{
//用户认证//无需使用(用不到)
function idValidationTest()
{
$Sso = new Sso();
$zarr=$Sso->idValidation("","");
return json($zarr);
}
//根据令牌获取第三方接入资源票据//无需使用(用不到)
function generateSTTest()
{
$Sso = new Sso();
$zarr=$Sso->generateST("");
return json($zarr);
}
//票据认证
function ticketValidationTest()
{
$Sso = new Sso();
$zarr=$Sso->ticketValidation("");
return json($zarr);
}
//根据令牌获取用户详细信息
function getUserInfoTest()
{
$Sso = new Sso();
$zarr=$Sso->getUserInfo("");
return json($zarr);
}
// 整合 【票据认证】【根据令牌获取用户详细信息】
function ticketValidationTest11()
{
$st = request()->param("st");//票据
$Sso = new Sso();
$ticketValidation=$Sso->ticketValidation($st);//票据认证
if (isset($ticketValidation['result']) && $ticketValidation['result'] =="0") {
$getUserInfo= $Sso->getUserInfo($ticketValidation['token']);//根据令牌获取用户详细信息
if (isset($getUserInfo['result']) && $getUserInfo['result'] =="0") {
//这里开始写个人业务逻辑
//这里开始写个人业务逻辑
//这里开始写个人业务逻辑
//这里开始写个人业务逻辑
//这里开始写个人业务逻辑
//这里开始写个人业务逻辑
}else{
return json_error($getUserInfo);
}
}else{
return json_error($ticketValidation);
}
}
}