Bitzsoft.Integrations.SsoRedirect
1.0.0-alpha.7
dotnet add package Bitzsoft.Integrations.SsoRedirect --version 1.0.0-alpha.7
NuGet\Install-Package Bitzsoft.Integrations.SsoRedirect -Version 1.0.0-alpha.7
<PackageReference Include="Bitzsoft.Integrations.SsoRedirect" Version="1.0.0-alpha.7" />
<PackageVersion Include="Bitzsoft.Integrations.SsoRedirect" Version="1.0.0-alpha.7" />
<PackageReference Include="Bitzsoft.Integrations.SsoRedirect" />
paket add Bitzsoft.Integrations.SsoRedirect --version 1.0.0-alpha.7
#r "nuget: Bitzsoft.Integrations.SsoRedirect, 1.0.0-alpha.7"
#:package Bitzsoft.Integrations.SsoRedirect@1.0.0-alpha.7
#addin nuget:?package=Bitzsoft.Integrations.SsoRedirect&version=1.0.0-alpha.7&prerelease
#tool nuget:?package=Bitzsoft.Integrations.SsoRedirect&version=1.0.0-alpha.7&prerelease
Bitzsoft.Integrations.SsoRedirect
SSO 跳转通用管道 — 通过纯配置对接任意 SSO 平台,无需编写代码。
功能
- 配置驱动:四种认证模式(UrlTemplate / AesEncryption / ApiRedirect / Pipeline)覆盖绝大多数 SSO 场景
- 管道可组合:Pipeline 模式支持任意步骤编排(加密、签名、JWT、API 调用),内置 11 种步骤 + 自定义步骤逃生口
- 多算法支持:AES(ECB/CBC)、RSA(PKCS1/OAEP)、HMAC-SHA256/SHA1、MD5、HS256 JWT
- API 跳转:支持 JSON 提取与 302 重定向两种 API 响应解析
- 第三方请求日志:内置 RequestLogging DelegatingHandler,记录 ApiRedirect / Pipeline API 步骤的 HTTP 请求与响应
- IConfiguration 绑定:支持从 appsettings.json 配置节加载全部参数
设计理念
传统做法是每个 SSO 供应商写一个 Provider 项目。SsoRedirect 将 SSO 跳转抽象为配置驱动的可组合管道:
| 模式 | 适用场景 | 原理 |
|---|---|---|
| UrlTemplate | 最常见 — URL 拼接 + 可选签名 | 替换模板占位符,可选 HMAC/MD5 签名 |
| AesEncryption | AES 加密令牌 | 构造明文 → AES 加密 → 拼接 URL |
| ApiRedirect | 需调 API 获取链接 | 调外部 API → 提取 URL(JSON 或 302 重定向) |
| Pipeline | 多步骤组合流程 | 自由编排加密、签名、JWT 请求头、API 调用等步骤 |
前三种为预设模式,覆盖 80% 场景。Pipeline 模式通过字典配置任意步骤组合,适用于 RSA → API → MD5 签名、JWT Bearer → API 等多步串联场景。
新对接一个 SSO 平台? 只需要配置,不需要新建项目。
安装
dotnet add package Bitzsoft.Integrations.SsoRedirect
快速开始
模式一:UrlTemplate(URL 模板替换)
最常用的模式。平台给一个 SSO URL 模板,你把参数填进去。
using Bitzsoft.Integrations.SsoRedirect;
// 例:法信
services.AddBitzsoftSsoRedirect(options =>
{
options.ProviderName = "法信";
options.AuthMode = SsoAuthMode.UrlTemplate;
options.SsoUrlTemplate = "https://www.faxin.cn/sso?uid={userId}&token={token}&t={timestamp}";
options.Token = "your-sso-token";
});
// 例:带 HMAC 签名的平台
services.AddBitzsoftSsoRedirect(options =>
{
options.ProviderName = "某平台";
options.AuthMode = SsoAuthMode.UrlTemplate;
options.SsoUrlTemplate = "https://sso.example.com/login?uid={userId}&t={timestamp}";
options.SignSecret = "your-hmac-secret";
options.SignAlgorithm = "HMAC-SHA256"; // 或 HMAC-SHA1、MD5
});
支持的占位符:
| 占位符 | 替换为 |
|---|---|
{userId} |
用户标识 |
{token} |
Token 配置值 |
{timestamp} |
当前 Unix 时间戳(秒) |
{redirectUrl} |
登录后跳转目标 |
配置 SignSecret 后,签名会自动作为 sign 查询参数追加到 URL。
模式二:AesEncryption(AES 加密)
平台要求加密令牌的场景。构造明文 → AES 加密 → Base64 → 拼接 URL。
// 例:威科先行(AES-ECB)
services.AddBitzsoftSsoRedirect(options =>
{
options.ProviderName = "wkinfo";
options.AuthMode = SsoAuthMode.AesEncryption;
options.Token = "your-app-secret";
options.AesKey = "your-app-secret";
options.AesCipherMode = "ECB";
options.AesPlainTextTemplate = "{timestamp}-{tenantName}";
options.TenantName = "your-tenant";
options.AesUrlTemplate = "https://law.wkinfo.com.cn/oauth/thirdParty/login?appId=your-app-id&cipher={cipher}";
});
// 例:AES-CBC 模式
services.AddBitzsoftSsoRedirect(options =>
{
options.ProviderName = "某平台";
options.AuthMode = SsoAuthMode.AesEncryption;
options.AesPlainTextTemplate = "{userId}|{timestampMs}|{token}";
options.AesKey = "your-32-byte-aes-key-here";
options.AesIv = "your-16-byte-iv";
options.AesCipherMode = "CBC";
options.AesUrlTemplate = "https://www.example.com/sso?loginid={userId}&ts={timestamp}&token={cipher}";
});
明文模板占位符:
| 占位符 | 替换为 |
|---|---|
{timestamp} |
Unix 时间戳(秒) |
{timestampMs} |
Unix 时间戳(毫秒) |
{userId} |
用户标识 |
{token} |
Token 配置值 |
{tenantName} |
TenantName 配置值 |
URL 模板占位符:
| 占位符 | 替换为 |
|---|---|
{cipher} |
AES 加密后的 Base64(已 URL 编码) |
{appId} |
AppId 配置值 |
{timestamp} |
Unix 时间戳(秒) |
{redirectUrl} |
登录后跳转目标 |
密钥不足 16/24/32 字节时自动补零,超过 32 字节会抛异常。
模式三:ApiRedirect(API 获取链接)
需要先调外部 API 获取访问链接或令牌的场景。
// 例:API 返回 JSON 中的 URL
services.AddBitzsoftSsoRedirect(options =>
{
options.ProviderName = "探案家";
options.AuthMode = SsoAuthMode.ApiRedirect;
options.ApiUrl = "https://api.example.com/getKey";
options.ApiMethod = "POST";
options.ApiBodyTemplate = "{\"userName\":\"{userId}\",\"appId\":\"{appId}\"}";
options.ApiResponseCodePath = "code";
options.ApiSuccessCode = "0";
options.ApiResponseUrlPath = "data.appKey";
options.ApiResultUrlTemplate = "https://jumpscope.cn/taj/assetVerification?appKey={apiResult}";
options.AppId = "your-app-id";
options.Token = "your-token";
});
// 例:API 返回 302 重定向
services.AddBitzsoftSsoRedirect(options =>
{
options.ProviderName = "某平台";
options.AuthMode = SsoAuthMode.ApiRedirect;
options.ApiUrl = "https://api.example.com/redirect?uid={userId}&t={timestamp}";
options.ApiMethod = "GET";
options.ApiResponseType = "redirect"; // 从 Location 头获取 URL
});
API 请求体占位符: {userId}、{appId}、{timestamp}、{token}
API 响应配置:
| 配置项 | 说明 | 默认值 |
|---|---|---|
ApiResponseType |
json 或 redirect |
json |
ApiResponseCodePath |
成功码的 JSON 路径 | code |
ApiSuccessCode |
成功码值 | 10000 |
ApiResponseUrlPath |
URL 的 JSON 路径 | —— |
ApiResultUrlTemplate |
最终 URL 模板,{apiResult} 为 API 返回数据 |
—— |
模式四:Pipeline(可组合步骤管道)
当 SSO 流程涉及多步骤串联(如 RSA 加密 → API 调用 → MD5 签名),预设模式无法满足时使用。
// 例:见微数据 — RSA 加密 → API 调用 → MD5 签名
services.AddBitzsoftSsoRedirect(options =>
{
options.ProviderName = "见微数据";
options.AuthMode = SsoAuthMode.Pipeline;
// 步骤链(按序执行)
options.PipelineSteps =
[
"template", // 1. 构造 RSA 明文 → PlainText
"rsa", // 2. RSA 加密 PlainText → CipherText
"template:requestBody", // 3. 构造 API 请求体(含密文)→ RequestBody
"apiCall", // 4. 调 API → ApiResult
"sign", // 5. MD5 签名 → Signature
"appendSignature", // 6. 追加签名到 URL
];
// 步骤模板
options.StepTemplates = new()
{
["template"] = """{"userId":"{userId}","timestamp":"{timestamp}","platform":"web_common"}""",
["template:requestBody"] = """{"codestr":"{cipher}","codeType":"jy","redirect":0}""",
};
// 步骤参数(键格式: "步骤名:参数名")
options.StepParameters = new()
{
["rsa:PublicKey"] = "MIIBIjANBg...",
["apiCall:Url"] = "https://api.jianweidata.com/getUserInstValidate",
["apiCall:Method"] = "POST",
["apiCall:ResponseUrlPath"] = "location",
["apiCall:ResponseCodePath"] = "code",
["apiCall:SuccessCode"] = "0",
["sign:Algorithm"] = "MD5",
["sign:Secret"] = "",
};
});
// 例:网核宝 — HS256 JWT Bearer 鉴权后调用 API
services.AddBitzsoftSsoRedirect(options =>
{
options.ProviderName = "网核宝";
options.AuthMode = SsoAuthMode.Pipeline;
options.Token = "{id}.{secret}"; // 网核宝 API Key
options.PipelineSteps =
[
"jwtBearer",
"template:requestBody",
"apiCall",
];
options.StepTemplates = new()
{
["template:requestBody"] = """{"caseCodes":["111111","222222"]}""",
};
options.StepParameters = new()
{
["apiCall:Url"] = "https://open.wanghebao.com/api/case_codes",
["apiCall:Method"] = "POST",
["apiCall:ResponseCodePath"] = "status",
["apiCall:SuccessCode"] = "true",
["apiCall:ResponseUrlPath"] = "",
};
});
内置步骤
| 步骤名 | 作用 | 读取 | 写入 |
|---|---|---|---|
template |
模板替换 | UserId, Timestamp 等 | PlainText |
template:url |
模板替换到 URL | UserId, CipherText 等 | Url |
template:requestBody |
模板替换到请求体 | CipherText 等 | RequestBody |
aes |
AES 加密 | PlainText | CipherText |
rsa |
RSA 公钥加密 | PlainText | CipherText |
sign |
计算签名 | Url 或 PlainText | Signature |
jwtBearer |
生成 HS256 JWT Bearer 请求头 | Token 或 jwtBearer 参数 | RequestHeaders.Authorization |
apiCall |
HTTP 调用 + JSON 提取 | RequestBody | ApiResult |
apiRedirect |
HTTP 302 Location 捕获 | RequestBody | Url |
buildUrl |
模板组装 URL | CipherText, ApiResult 等 | Url |
appendSignature |
追加签名查询参数 | Signature, Url | Url |
步骤参数键
| 参数键 | 适用步骤 | 说明 |
|---|---|---|
rsa:PublicKey |
rsa | RSA 公钥(Base64 SPKI 格式) |
rsa:Padding |
rsa | PKCS1(默认)或 OAEP |
sign:Algorithm |
sign | HMAC-SHA256 / HMAC-SHA1 / MD5 |
sign:Secret |
sign | 签名密钥 |
sign:Data |
sign | url(默认)或 plaintext |
jwtBearer:ApiKey |
jwtBearer | API Key,格式 {id}.{secret};未配置时使用 Token |
jwtBearer:AppId |
jwtBearer | AppId;未配置 ApiKey 时与 Secret 配合使用 |
jwtBearer:Secret |
jwtBearer | HS256 签名密钥 |
jwtBearer:IncludeExpiry |
jwtBearer | 是否写入 expiryTimestamp,默认 false |
jwtBearer:ExpiresInSeconds |
jwtBearer | 过期秒数,默认 1800 |
apiCall:Url |
apiCall | API 地址 |
apiCall:Method |
apiCall | POST(默认)或 GET |
apiCall:ResponseUrlPath |
apiCall | URL 的 JSON 路径 |
apiCall:ResponseCodePath |
apiCall | 成功码 JSON 路径 |
apiCall:SuccessCode |
apiCall | 成功码值 |
buildUrl:Template |
buildUrl | URL 模板 |
自定义步骤
当内置步骤无法满足需求时,可通过委托注入自定义逻辑:
options.CustomSteps = new()
{
["myCustomStep"] = (context, ct) =>
{
context.ExtraParams["customKey"] = "computed-value";
return ValueTask.CompletedTask;
},
};
使用服务
using Bitzsoft.Integrations.SsoRedirect;
public class SsoService
{
private readonly SsoRedirectProvider _provider;
public SsoService(SsoRedirectProvider provider)
{
_provider = provider;
}
public async Task<string> GetLoginUrlAsync(string userId, string? redirectTo = null)
{
var result = await _provider.GenerateAccessUrlAsync(userId, redirectTo);
Console.WriteLine($"链接在 {result.ExpiresAt:HH:mm:ss} 过期");
return result.Url;
}
}
从 IConfiguration 绑定
// appsettings.json
// {
// "SsoRedirect": {
// "ProviderName": "某平台",
// "AuthMode": "UrlTemplate",
// "SsoUrlTemplate": "https://...",
// "Token": "..."
// }
// }
services.AddBitzsoftSsoRedirect(configuration, "SsoRedirect");
第三方请求日志
内置 Bitzsoft.Integrations.RequestLogging 出站请求记录管道,默认使用 NullRequestLogStore 不持久化。
// ① 默认:启用记录管道但不持久化(日志丢弃)
services.AddBitzsoftSsoRedirect(options => { /* ... */ });
// ② 持久化:宿主注册 IRequestLogStore 实现后,所有出站请求自动落库
services.AddRequestLogging<MyRequestLogStore>(opts =>
{
opts.MaxBodyLength = 8192;
opts.SensitiveFields.Add("mySecret");
});
services.AddBitzsoftSsoRedirect(options => { /* ... */ });
完整配置参考
通用配置
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ProviderName |
string |
—— | 供应商名称(必填) |
BaseUrl |
string |
—— | 平台基础 URL |
AuthMode |
SsoAuthMode |
UrlTemplate |
认证模式 |
Token |
string |
—— | 预共享令牌 |
TenantName |
string? |
—— | 租户名称({tenantName} 占位符) |
DefaultRedirectUrl |
string? |
—— | 默认跳转目标 |
UrlExpiresIn |
TimeSpan |
30 min | 链接有效期 |
UrlTemplate 模式
| 配置项 | 说明 |
|---|---|
SsoUrlTemplate |
URL 模板(必填) |
SignSecret |
签名密钥(可选) |
SignAlgorithm |
HMAC-SHA256 / HMAC-SHA1 / MD5 |
AesEncryption 模式
| 配置项 | 说明 |
|---|---|
AesPlainTextTemplate |
明文模板(必填) |
AesKey |
AES 密钥,默认使用 Token |
AesIv |
IV(CBC 模式用,ECB 忽略) |
AesCipherMode |
ECB(默认)或 CBC |
AesUrlTemplate |
加密后的 URL 模板(必填) |
AppId |
应用 ID(替换 {appId}) |
AesExtraParams |
追加到 URL 的额外查询参数 |
ApiRedirect 模式
| 配置项 | 说明 |
|---|---|
ApiUrl |
API 地址(必填) |
ApiMethod |
POST(默认)或 GET |
ApiBodyTemplate |
POST 请求体 JSON 模板 |
ApiResponseType |
json(默认)或 redirect |
ApiResponseCodePath |
成功码 JSON 路径 |
ApiSuccessCode |
成功码值 |
ApiResponseUrlPath |
URL 的 JSON 路径 |
ApiResultUrlTemplate |
最终 URL 模板 |
Pipeline 模式
| 配置项 | 说明 |
|---|---|
PipelineSteps |
步骤名称有序列表 |
StepParameters |
步骤参数字典(键格式:步骤名:参数名) |
StepTemplates |
步骤模板字典(键为步骤名或 步骤名:目标) |
CustomSteps |
自定义步骤委托(逃生口) |
已对接供应商
| 包名 | 供应商 | 模式 |
|---|---|---|
LegalDatabase.WkInfo |
威科先行(WkInfo) | AesEncryption (ECB) |
LegalDatabase.Faxin |
法信 | UrlTemplate |
LegalDatabase.Jianwei |
见微数据 | Pipeline (RSA → API → MD5) |
LegalDatabase.Jufaanli |
聚法案例 | UrlTemplate |
LegalDatabase.Wusong |
无讼 | UrlTemplate |
LegalDatabase.Lexisnexis |
律商联讯 | UrlTemplate |
LegalDatabase.Lawsdata |
Lawsdata | UrlTemplate |
SsoRedirect.Qixinbao |
启信宝 SSO | SimpleStringCipher |
SsoRedirect.QccSso |
企查查 SSO | SimpleStringCipher |
核心类型
| 类型 | 说明 |
|---|---|
SsoRedirectProvider |
SSO 跳转核心引擎(IDisposable) |
SsoRedirectOptions |
全模式配置选项 |
SsoRedirectResult |
跳转结果(Url + ExpiresAt) |
SsoRedirectContext |
管道上下文(步骤间状态传递) |
SsoAuthMode |
认证模式枚举 |
依赖
Microsoft.Extensions.Http— HttpClient 工厂支持(ApiRedirect / Pipeline API 步骤)Bitzsoft.Integrations.Compatibility— 基础工具库
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Bitzsoft.Integrations.Compatibility (>= 1.0.0-alpha.7)
- Bitzsoft.Integrations.RequestLogging (>= 1.0.0-alpha.7)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Http (>= 10.0.9)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.9)
-
net5.0
- Bitzsoft.Integrations.Compatibility (>= 1.0.0-alpha.7)
- Bitzsoft.Integrations.RequestLogging (>= 1.0.0-alpha.7)
- Microsoft.Extensions.Configuration.Abstractions (>= 5.0.0)
- Microsoft.Extensions.Http (>= 5.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 5.0.0)
-
net8.0
- Bitzsoft.Integrations.Compatibility (>= 1.0.0-alpha.7)
- Bitzsoft.Integrations.RequestLogging (>= 1.0.0-alpha.7)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Http (>= 10.0.9)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.9)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Bitzsoft.Integrations.SsoRedirect:
| Package | Downloads |
|---|---|
|
Bitzsoft.Integrations.LegalDatabase
法规案例库抽象层 — 统一接口定义、基础模型与 SSO 跳转管道 |
|
|
Bitzsoft.Integrations.SsoRedirect.Qixinbao
启信宝 SSO 跳转集成 — 加密令牌自动登录 |
|
|
Bitzsoft.Integrations.SsoRedirect.QccSso
企查查 SSO 跳转集成 — 加密令牌自动登录 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-alpha.7 | 113 | 6/16/2026 |
| 1.0.0-alpha.6 | 121 | 6/16/2026 |
| 1.0.0-alpha.5 | 109 | 6/14/2026 |
| 1.0.0-alpha.3 | 118 | 6/7/2026 |