C#如何实现OpenID Connect身份认证并集成IdentityServer

来源:建站技术作者:台湾程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《C#如何实现OpenID Connect身份认证并集成IdentityServer》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#如何实现OpenID Connect身份认证并集成IdentityServer》有用,将其分享出去将是对创作者最好的鼓励。

在C#应用开发中,OpenID Connect作为基于OAuth 2.0的身份认证协议,能够安全地实现用户身份验证和授权,而IdentityServer是.NET生态中常用的OpenID Connect和OAuth 2.0框架,二者结合可以满足企业级应用的身份认证需求。

C#如何实现OpenID Connect身份认证并集成IdentityServer

基础概念说明

OpenID Connect简称OIDC,它在OAuth 2.0的基础上增加了身份认证层,能够让客户端应用验证用户身份,并获取用户的基本信息。IdentityServer是一个开源的框架,支持OIDC和OAuth 2.0协议,可以作为独立的身份认证服务,为多个客户端应用提供统一的身份认证能力。

环境准备

首先需要准备两个项目,一个是IdentityServer服务端项目,另一个是需要接入认证的C#客户端应用,这里以ASP.NET Core Web应用为例。两个项目都基于.NET 6及以上版本开发,需要安装对应的NuGet包。

IdentityServer服务端依赖

在IdentityServer项目中安装以下NuGet包:

  • IdentityServer4
  • IdentityServer4.AspNetIdentity

客户端应用依赖

在客户端应用中安装以下NuGet包:

  • Microsoft.AspNetCore.Authentication.OpenIdConnect
  • Microsoft.IdentityModel.Protocols.OpenIdConnect

IdentityServer服务端配置

首先配置IdentityServer的基础信息,包括API资源、客户端信息、身份资源等。

定义客户端配置

在IdentityServer项目中添加客户端配置类,定义允许接入的客户端应用信息:

// 客户端配置类
public static class ClientConfig
{
    public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
        {
            new Client
            {
                // 客户端唯一标识
                ClientId = "csharp_client",
                // 客户端名称
                ClientName = "C#示例客户端",
                // 客户端密钥,用于验证客户端身份
                ClientSecrets = { new Secret("client_secret_123".Sha256()) },
                // 授权类型,这里使用授权码模式
                AllowedGrantTypes = GrantTypes.Code,
                // 重定向地址,认证完成后跳转的客户端地址
                RedirectUris = { "https://localhost:5002/signin-oidc" },
                // 登出后重定向地址
                PostLogoutRedirectUris = { "https://localhost:5002/signout-callback-oidc" },
                // 允许的Scope,包括OpenID和用户信息相关Scope
                AllowedScopes = new List<string>
                {
                    "openid",
                    "profile",
                    "email"
                },
                // 允许通过浏览器传递访问令牌
                AllowAccessTokensViaBrowser = true
            }
        };
    }
}

配置IdentityServer服务

在IdentityServer项目的Program.cs中添加IdentityServer服务配置:

var builder = WebApplication.CreateBuilder(args);

// 添加IdentityServer服务
builder.Services.AddIdentityServer()
    // 添加开发环境的临时证书,生产环境需要替换为正式证书
    .AddDeveloperSigningCredential()
    // 添加内存中的客户端配置
    .AddInMemoryClients(ClientConfig.GetClients())
    // 添加内存中的身份资源,openid和profile是OIDC标准资源
    .AddInMemoryIdentityResources(new List<IdentityResource>
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
        new IdentityResources.Email()
    });

var app = builder.Build();

// 启用IdentityServer中间件
app.UseIdentityServer();

app.MapGet("/", () => "IdentityServer服务运行中");

app.Run();

客户端应用集成配置

接下来配置客户端应用,使其能够通过OpenID Connect协议对接IdentityServer完成身份认证。

添加认证服务配置

在客户端应用的Program.cs中配置认证服务:

var builder = WebApplication.CreateBuilder(args);

// 添加认证服务,使用Cookie和OpenID Connect方案
builder.Services.AddAuthentication(options =>
{
    // 默认方案使用Cookie
    options.DefaultScheme = "Cookies";
    // 默认质询方案使用OpenID Connect
    options.DefaultChallengeScheme = "oidc";
})
// 添加Cookie认证方案,用于保存用户登录状态
.AddCookie("Cookies")
// 添加OpenID Connect认证方案,对接IdentityServer
.AddOpenIdConnect("oidc", options =>
{
    // IdentityServer的地址
    options.Authority = "https://localhost:5001";
    // 是否要求HTTPS,开发环境可以设为false,生产环境必须为true
    options.RequireHttpsMetadata = false;
    // 客户端Id,需要和IdentityServer中配置的ClientId一致
    options.ClientId = "csharp_client";
    // 客户端密钥,需要和IdentityServer中配置的ClientSecrets一致
    options.ClientSecret = "client_secret_123";
    // 响应类型,授权码模式对应code
    options.ResponseType = "code";
    // 请求的Scope,需要和IdentityServer中允许的Scope匹配
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("email");
    // 是否保存令牌到Cookie中
    options.SaveTokens = true;
    // 是否从UserInfo端点获取用户信息
    options.GetClaimsFromUserInfoEndpoint = true;
});

// 添加控制器和视图支持
builder.Services.AddControllersWithViews();

var app = builder.Build();

// 启用认证中间件
app.UseAuthentication();
// 启用授权中间件
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

添加受保护的页面

在客户端应用中添加一个需要登录才能访问的控制器,验证认证是否生效:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace ClientApp.Controllers
{
    [Authorize]
    public class UserController : Controller
    {
        public IActionResult Index()
        {
            // 获取用户身份信息
            var userName = User.Identity.Name;
            ViewBag.UserName = userName;
            return View();
        }
    }
}

对应的视图文件User/Index.cshtml内容如下:

<h2>用户信息页面</h2>
<p>当前登录用户:@ViewBag.UserName</p>
<a asp-controller="Home" asp-action="Logout">退出登录</a>

添加登出功能

在Home控制器中添加登出方法,同时清除本地Cookie和IdentityServer的登录状态:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;

namespace ClientApp.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public async Task<IActionResult> Logout()
        {
            // 清除本地Cookie认证状态
            await HttpContext.SignOutAsync("Cookies");
            // 跳转到IdentityServer的登出端点,清除IdentityServer的登录状态
            return Redirect("https://localhost:5001/connect/endsession");
        }
    }
}

功能验证

启动IdentityServer项目,端口为5001,再启动客户端应用,端口为5002。访问客户端应用的/User/Index页面,会自动跳转到IdentityServer的登录页面,完成登录后会跳转回客户端页面,显示当前登录用户信息。点击退出登录按钮,会清除所有登录状态,再次访问受保护页面需要重新登录。

注意事项

  • 生产环境中需要为IdentityServer配置正式的签名证书,不能使用开发环境的临时证书
  • ClientSecret需要妥善保管,不能泄露到客户端代码中
  • 重定向地址需要和IdentityServer中配置的完全一致,否则会导致认证失败
  • 如果需要获取更多用户信息,需要在IdentityServer中配置对应的身份资源,并在客户端请求对应的Scope

C#OpenID_ConnectIdentityServer身份认证修改时间:2026-07-08 03:39:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。