You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Asp.Net Core 3.1 基于同一Identity实例配置3个Web应用SSO及跨站角色

需求可行性

你提到的跨站SSO、统一角色权限覆盖3个站点的需求完全可以实现,和旧版.NET Membership的应用标识、目录级权限逻辑可以完全对齐,具体实现方案如下:


方案选型前置说明

如果你的3个站点属于同根域名(比如site1.xxx.com、site2.xxx.com、auth.xxx.com),优先用共享Cookie的轻量方案;如果是不同根域名,用基于OpenID Connect的统一身份提供商(IdP)方案即可。


方案1:同根域名共享Cookie实现SSO

步骤1:统一认证端配置

搭建独立的ASP.NET Core Identity站点作为统一认证入口,首先扩展Identity存储适配你的业务逻辑:

  • 若要实现旧版Membership的应用ID访问控制,可新增UserApplications关联表,存储用户ID与允许访问的应用ID映射关系
  • 全局角色直接使用原生AspNetRoles表存储即可,无需额外改造

然后配置Cookie与DataProtection:

// 注册Identity服务
builder.Services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<AuthDbContext>()
    .AddDefaultTokenProviders();

// 配置共享Cookie
builder.Services.ConfigureApplicationCookie(options =>
{
    options.Cookie.Name = ".UnifiedAuthCookie";
    options.Cookie.Domain = ".yourdomain.com"; // 前缀带点,适配所有子域名
    options.Cookie.HttpOnly = true;
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
    options.LoginPath = "/Account/Login";
    options.LogoutPath = "/Account/Logout";
});

// 配置统一的DataProtection密钥,所有站点必须一致
builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\shared-storage\dp-keys")) // 存在所有站点都能访问的共享路径,也可以存在Redis、数据库中
    .SetApplicationName("UnifiedAuthSystem"); // 所有站点的这个配置必须完全相同
步骤2:3个业务站点配置

所有业务站点无需部署独立的Identity体系,只需要配置相同的Cookie和DataProtection即可:

// 同认证端的DataProtection配置,完全一致
builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(@"\\shared-storage\dp-keys"))
    .SetApplicationName("UnifiedAuthSystem");

// 配置认证方案,跳转统一认证端登录
builder.Services.AddAuthentication(IdentityConstants.ApplicationScheme)
    .AddCookie(IdentityConstants.ApplicationScheme, options =>
    {
        options.Cookie.Name = ".UnifiedAuthCookie";
        options.Cookie.Domain = ".yourdomain.com";
        options.LoginPath = "https://auth.yourdomain.com/Account/Login";
        options.LogoutPath = "https://auth.yourdomain.com/Account/Logout";
    });

方案2:不同根域名场景

如果3个站点是完全不同的根域名,共享Cookie无法生效,直接在统一认证端集成OpenIddict或IdentityServer即可,两者都和ASP.NET Core Identity原生兼容:

  • 3个站点作为OIDC客户端,所有登录、授权请求都跳转统一认证端处理
  • 用户登录成功后,认证端会将用户角色、允许访问的应用ID等信息写入ID Token,业务站点解析Token即可拿到权限信息,无需单独存储用户、角色数据

统一角色权限实现逻辑

  1. 全局角色覆盖:认证端在用户登录成功后,将用户的所有角色写入Claims,业务站点直接使用原生的[Authorize(Roles = "角色名")]特性即可做权限校验,无需单独维护角色数据
  2. 应用ID访问控制:认证端登录时校验当前请求的应用ID是否在用户允许的应用列表中,不在则直接拒绝授权;也可以将允许的应用ID列表写入Claims,业务站点可自行二次校验
  3. 目录/文件夹级权限:如果需要和旧版Membership一样做路径级权限控制,自定义授权策略即可,示例如下:
// 自定义路径权限校验规则
public class PathAccessRequirement : IAuthorizationRequirement { }
public class PathAccessHandler : AuthorizationHandler<PathAccessRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PathAccessRequirement requirement)
    {
        if (context.Resource is not HttpContext httpContext) return Task.CompletedTask;
        var currentRequestPath = httpContext.Request.Path.Value.ToLower();
        // 从Claims中取当前用户被授权的所有路径前缀
        var allowedPaths = context.User.Claims
            .Where(c => c.Type == "AllowedPath")
            .Select(c => c.Value.ToLower())
            .ToList();
        if (allowedPaths.Any(p => currentRequestPath.StartsWith(p)))
        {
            context.Succeed(requirement);
        }
        return Task.CompletedTask;
    }
}

注册策略后直接用[Authorize(Policy = "PathAccess")]标记需要校验的控制器或Action即可。


注意事项

  • 所有站点的DataProtection配置必须完全一致,否则无法互相解密认证信息
  • 用户、角色、应用权限数据只需要在统一认证端维护,不需要同步到各个业务站点,避免数据不一致
  • 统一退出登录时,需要先调用认证端的退出接口,再清除业务站点本地的认证Cookie

内容的提问来源于stack exchange,提问作者user307537

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 12:30:04