在现代应用程序开发中,用户身份验证是一个至关重要的部分。随着微服务架构和分布式系统的普及,传统的身份验证方式已经无法满足需求。IdentityServer4 是一个开源的身份验证和授权框架,它基于 OpenID Connect 和 OAuth 2.0 协议,能够为应用程序提供强大的身份验证和授权功能。
本文将详细介绍如何使用 IdentityServer4 和 OpenID Connect 添加用户身份验证。我们将从基本概念开始,逐步深入到实际实现,帮助开发者理解并掌握这一技术。
IdentityServer4 是一个基于 .NET Core 的开源框架,用于实现身份验证和授权。它支持 OpenID Connect 和 OAuth 2.0 协议,能够为应用程序提供单点登录(SSO)、API 访问控制等功能。IdentityServer4 可以作为身份提供者(Identity Provider, IdP),为多个客户端应用程序提供统一的身份验证服务。
OpenID Connect 是建立在 OAuth 2.0 协议之上的身份验证层。它允许客户端应用程序通过身份提供者(如 IdentityServer4)验证用户身份,并获取用户的基本信息。OpenID Connect 提供了一种标准化的方式来实现单点登录(SSO)和用户身份验证。
在开始使用 IdentityServer4 之前,我们需要了解一些核心概念:
首先,我们需要创建一个新的 .NET Core 项目,并添加 IdentityServer4 的依赖。
dotnet new webapi -n IdentityServerDemo cd IdentityServerDemo dotnet add package IdentityServer4
在 Startup.cs
文件中,配置 IdentityServer4 服务。
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddIdentityServer() .AddDeveloperSigningCredential() // 用于开发环境的临时签名证书 .AddInMemoryClients(Config.GetClients()) // 配置客户端 .AddInMemoryIdentityResources(Config.GetIdentityResources()) // 配置身份资源 .AddInMemoryApiResources(Config.GetApiResources()) // 配置 API 资源 .AddTestUsers(Config.GetUsers()); // 添加测试用户 } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseIdentityServer(); } }
在 Config.cs
文件中,定义客户端、身份资源和 API 资源。
public static class Config { public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { ClientId = "client", AllowedGrantTypes = GrantTypes.Code, ClientSecrets = { new Secret("secret".Sha256()) }, AllowedScopes = { "openid", "profile", "api1" }, RedirectUris = { "https://localhost:5001/signin-oidc" }, PostLogoutRedirectUris = { "https://localhost:5001/signout-callback-oidc" } } }; } public static IEnumerable<IdentityResource> GetIdentityResources() { return new List<IdentityResource> { new IdentityResources.OpenId(), new IdentityResources.Profile() }; } public static IEnumerable<ApiResource> GetApiResources() { return new List<ApiResource> { new ApiResource("api1", "My API") }; } public static List<TestUser> GetUsers() { return new List<TestUser> { new TestUser { SubjectId = "1", Username = "alice", Password = "password" } }; } }
接下来,我们创建一个客户端应用程序,用于与 IdentityServer4 进行交互。
dotnet new mvc -n ClientApp cd ClientApp dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
在 Startup.cs
文件中,配置 OpenID Connect 身份验证。
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; options.DefaultChallengeScheme = "oidc"; }) .AddCookie("Cookies") .AddOpenIdConnect("oidc", options => { options.Authority = "https://localhost:5000"; options.ClientId = "client"; options.ClientSecret = "secret"; options.ResponseType = "code"; options.SaveTokens = true; options.Scope.Add("api1"); options.Scope.Add("profile"); }); services.AddControllersWithViews(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } }
在客户端应用程序中,我们可以通过 SignInAsync
和 SignOutAsync
方法实现用户的登录和注销。
public class AccountController : Controller { public IActionResult Login(string returnUrl = "/") { return Challenge(new AuthenticationProperties { RedirectUri = returnUrl }, "oidc"); } public IActionResult Logout() { return SignOut(new AuthenticationProperties { RedirectUri = "/" }, "Cookies", "oidc"); } }
在客户端应用程序中,我们可以通过 HttpContext.User
获取当前用户的信息。
public class HomeController : Controller { public IActionResult Index() { var user = HttpContext.User; return View(user); } }
首先,我们创建一个受保护的 API 项目。
dotnet new webapi -n ProtectedApi cd ProtectedApi dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
在 Startup.cs
文件中,配置 JWT 身份验证。
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { options.Authority = "https://localhost:5000"; options.TokenValidationParameters = new TokenValidationParameters { ValidateAudience = false }; }); services.AddAuthorization(options => { options.AddPolicy("ApiScope", policy => { policy.RequireAuthenticatedUser(); policy.RequireClaim("scope", "api1"); }); }); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
在 API 控制器中,使用 [Authorize]
属性保护端点。
[ApiController] [Route("[controller]")] public class ValuesController : ControllerBase { [HttpGet] [Authorize(Policy = "ApiScope")] public IActionResult Get() { return Ok(new { message = "This is a protected API endpoint." }); } }
在 IdentityServer4 和客户端应用程序之间,可能会遇到跨域问题。可以通过配置 CORS 策略来解决。
services.AddCors(options => { options.AddPolicy("AllowAll", builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); }); }); app.UseCors("AllowAll");
IdentityServer4 提供了丰富的扩展点,可以通过实现 IProfileService
接口来自定义用户身份验证流程。
public class CustomProfileService : IProfileService { public Task GetProfileDataAsync(ProfileDataRequestContext context) { // 自定义用户信息 context.IssuedClaims = context.Subject.Claims.ToList(); return Task.CompletedTask; } public Task IsActiveAsync(IsActiveContext context) { // 自定义用户激活状态 context.IsActive = true; return Task.CompletedTask; } }
IdentityServer4 支持多租户配置,可以通过动态加载客户端和资源来实现多租户支持。
services.AddIdentityServer() .AddClientStore<CustomClientStore>() .AddResourceStore<CustomResourceStore>();
通过本文的介绍,我们了解了如何使用 IdentityServer4 和 OpenID Connect 添加用户身份验证。从基本概念到实际实现,我们逐步掌握了 IdentityServer4 的配置和使用方法。IdentityServer4 提供了强大的身份验证和授权功能,能够满足现代应用程序的需求。希望本文能够帮助开发者在实际项目中更好地应用 IdentityServer4 和 OpenID Connect。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。