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

基础概念说明
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