跳到主要内容

SSO 单点登录

Identity 的认证能力可对接基于 OpenIddict 实现的 OAuth2/OIDC 单点登录:多个业务应用共享同一个认证入口,用户登录一次即可访问所有受信应用;微服务之间也通过同一套 Token 完成校验。

架构

Auth.Host 是统一认证方,底层身份数据来自 Identity;业务模块不再各自实现登录,而是信任 Auth.Host 签发的 Token。

快速开始

1. 部署 Auth 模块

dotnet run --project src/Services/Auth/FreeKit.Host

2. 配置业务模块

{
"Security": {
"OpenIddict": {
"Authority": "https://auth.example.com",
"ClientId": "my-app",
"ClientSecret": "my-secret",
"Scope": ["openid", "profile", "email"]
}
}
}

3. 注册认证服务

builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = OpenIddictValidationDefaults.AuthenticationScheme;
})
.AddOpenIddictValidation(options =>
{
options.Authority = configuration["Security:OpenIddict:Authority"];
options.ClientId = configuration["Security:OpenIddict:ClientId"];
options.ClientSecret = configuration["Security:OpenIddict:ClientSecret"];
});

配置选项

{
"Security": {
"Sso": {
"TokenExpiresIn": 86400,
"CodeExpiresInMinutes": 5
},
"OpenIddict": {
"Authority": "https://auth.example.com",
"ClientId": "my-app",
"ClientSecret": "my-secret",
"Scope": ["openid", "profile", "email", "roles"]
}
}
}

认证流程

授权码流程

刷新令牌流程

账号绑定流程(社交登录)

当用户已在 Identity 登录、再把第三方账号绑定时,走"绑定回调"而非"登录回调",绑定关系落到 IdentityUserLogin,最终仍是同一个 IdentityUser

前端集成

JavaScript 客户端

// 使用 oidc-client
import { UserManager } from 'oidc-client';

const config = {
authority: 'https://auth.example.com',
client_id: 'my-app',
redirect_uri: 'https://myapp.example.com/callback',
scope: 'openid profile email',
response_type: 'code'
};

const userManager = new UserManager(config);

// 登录
await userManager.signinRedirect();

// 登录回调
const user = await userManager.signinRedirectCallback();

// 获取 Token
const user = await userManager.getUser();
const token = user.access_token;

.NET 客户端

// 添加认证
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIddictDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIddict(options =>
{
options.ClientId("my-app");
options.ClientSecret("my-secret");
options.Authority("https://auth.example.com");
options.Scope("openid");
options.Scope("profile");
options.Scope("email");
});

// 使用
[Authorize]
public class ProtectedController : FreeKitController
{
[HttpGet]
public IActionResult Get()
{
return Ok(new { User = CurrentUser });
}
}

运维建议

建议说明
使用 HTTPS生产环境必须使用 HTTPS
定期轮换密钥定期轮换 ClientSecret
监控监控 Token 颁发和使用
备份定期备份授权数据

故障排查

问题解决方案
认证失败检查 Authority 和 ClientId
Token 无效检查 Token 过期时间
跨域问题配置 CORS

相关文档