对接致远OA单点登录的例子
时间: 2023-07-05 13:20:49 浏览: 155
对接致远OA单点登录,需要实现以下步骤:
1. 在致远OA系统中,配置单点登录参数,包括应用系统的名称、登录地址、退出地址等信息,并生成密钥和向量。
2. 在应用系统中,使用C#语言实现单点登录的逻辑,包括接收和解析来自致远OA系统的加密字符串、校验签名、验证时间戳等操作。
以下是一个简单的示例代码,用于演示如何实现对接致远OA单点登录:
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Security.Cryptography;
using System.Text;
public partial class SsoLogin : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// 从请求参数中获取加密字符串
string encryptData = Request.QueryString["data"];
// 解密字符串
string decryptedData = Decrypt(encryptData);
// 解析字符串
Dictionary<string, string> dataDict = ParseData(decryptedData);
// 校验签名
if (!VerifySignature(dataDict))
{
Response.Write("Invalid signature");
return;
}
// 验证时间戳
if (!VerifyTimestamp(dataDict))
{
Response.Write("Invalid timestamp");
return;
}
// 获取用户名和用户ID
string username = dataDict["username"];
string userId = dataDict["userid"];
// 在应用系统中进行单点登录
// ...
// 跳转到应用系统的首页
Response.Redirect("home.aspx");
}
// 解密方法
private string Decrypt(string encryptData)
{
// 根据实际情况,使用致远OA系统中生成的密钥和向量进行解密
byte[] key = Encoding.ASCII.GetBytes("1234567890123456");
byte[] iv = Encoding.ASCII.GetBytes("abcdefghijklmnop");
byte[] encryptedBytes = Convert.FromBase64String(encryptData);
string decryptedData = "";
using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
{
aes.Key = key;
aes.IV = iv;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (MemoryStream ms = new MemoryStream(encryptedBytes))
{
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs))
{
decryptedData = sr.ReadToEnd();
}
}
}
}
return decryptedData;
}
// 解析数据方法
private Dictionary<string, string> ParseData(string decryptedData)
{
Dictionary<string, string> dataDict = new Dictionary<string, string>();
string[] dataArray = decryptedData.Split('&');
foreach (string data in dataArray)
{
string[] keyValue = data.Split('=');
dataDict[keyValue[0]] = keyValue[1];
}
return dataDict;
}
// 校验签名方法
private bool VerifySignature(Dictionary<string, string> dataDict)
{
// 根据实际情况,使用致远OA系统中生成的密钥和向量进行签名校验
string key = "1234567890123456";
string iv = "abcdefghijklmnop";
string data = dataDict["data"];
string signature = dataDict["signature"];
byte[] keyBytes = Encoding.ASCII.GetBytes(key);
byte[] ivBytes = Encoding.ASCII.GetBytes(iv);
byte[] dataBytes = Encoding.ASCII.GetBytes(data);
using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
{
aes.Key = keyBytes;
aes.IV = ivBytes;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (MemoryStream ms = new MemoryStream(dataBytes))
{
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs))
{
string decryptedData = sr.ReadToEnd();
string computedSignature = ComputeSignature(decryptedData, key);
return signature.Equals(computedSignature);
}
}
}
}
}
// 计算签名方法
private string ComputeSignature(string decryptedData, string key)
{
byte[] keyBytes = Encoding.ASCII.GetBytes(key);
byte[] dataBytes = Encoding.ASCII.GetBytes(decryptedData);
HMACSHA1 hmac = new HMACSHA1(keyBytes);
byte[] signatureBytes = hmac.ComputeHash(dataBytes);
return Convert.ToBase64String(signatureBytes);
}
// 验证时间戳方法
private bool VerifyTimestamp(Dictionary<string, string> dataDict)
{
// 根据实际情况,可以设置一个有效时间段,超过该时间段的请求将被视为无效
string timestamp = dataDict["timestamp"];
DateTime dateTime = DateTime.ParseExact(timestamp, "yyyyMMddHHmmss", null);
TimeSpan timeSpan = DateTime.Now - dateTime;
return timeSpan.TotalMinutes <= 5;
}
}
```
以上代码仅作为参考,实际对接过程中需要根据具体情况进行修改和调整。