Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
C# .NET中基于JWT和外部授权服务器的REST API安全配置指南_创想鸟

C# .NET中基于JWT和外部授权服务器的REST API安全配置指南

C# .NET中基于JWT和外部授权服务器的REST API安全配置指南

本文旨在提供一个简洁明了的教程,指导开发者如何在C# .NET应用中,以纯资源服务器模式,通过外部授权服务器(如AWS Cognito或Asgardeo)实现REST API的安全保护。文章将重点介绍如何利用JWT Bearer认证机制,通过最小化配置,快速构建一个能够验证传入访问令牌的API服务,无需深度集成用户管理功能。

核心概念:JWT Bearer认证与资源服务器

在现代微服务架构中,api安全通常通过oauth 2.0和openid connect协议实现,其中json web token (jwt) 作为访问令牌的标准格式。资源服务器(resource server)是托管受保护资源的api服务,其主要职责是验证传入请求中的访问令牌,并根据令牌的有效性和权限信息决定是否授予访问。

对于从Java Spring Boot等其他平台迁移到C# .NET的开发者而言,如何以简洁高效的方式实现REST API的安全保护,尤其是作为纯资源服务器的角色,常常是一个挑战。许多教程倾向于将用户管理与API安全紧密结合,但这并非总是纯资源服务器所需的场景。本教程将展示如何在C# .NET中,通过最小化配置,实现一个专注于令牌验证的资源服务器。

配置步骤

在C# .NET(本示例基于.NET 6.0)中实现JWT Bearer认证的资源服务器,主要涉及以下三个步骤:

1. 添加认证服务

在应用程序的Program.cs文件中,需要配置认证服务,指定使用JWT Bearer认证方案。这包括设置默认的认证和挑战方案,并配置JWT Bearer选项,如受众(Audience)和OpenID Connect元数据地址。

using Microsoft.AspNetCore.Authentication.JwtBearer;using Microsoft.IdentityModel.Tokens;var builder = WebApplication.CreateBuilder(args);// 添加认证服务builder.Services.AddAuthentication(options =>{    // 设置默认的认证方案为JwtBearer    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;    // 设置默认的挑战方案为JwtBearer    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(options =>{    // 配置JWT Bearer选项    // Audience (受众) 是验证令牌时检查的声明之一,通常是客户端ID或资源服务器的标识符。    // 它确保令牌是为预期接收者颁发的。    options.Audience = "";     // MetadataAddress (元数据地址) 指向外部授权服务器的OpenID Connect配置发现文档。    // .NET认证中间件将从该地址自动获取公钥(JWKS URI)、颁发者(Issuer)等信息,    // 用于验证JWT令牌的签名和有效性。    options.MetadataAddress = "https://api.asgardeo.io/t//oauth2/token/.well-known/openid-configuration";    // 如果需要更精细的控制,例如自定义令牌验证参数,可以在这里进一步配置TokenValidationParameters。    // options.TokenValidationParameters = new TokenValidationParameters    // {    //     ValidateIssuer = true,    //     ValidIssuer = "https://api.asgardeo.io/t//oauth2/token",    //     ValidateAudience = true,    //     ValidAudience = "",    //     ValidateLifetime = true,    //     ClockSkew = TimeSpan.Zero // 允许的时间偏移量,建议设置为零或较小值    // };});// 其他服务注册,例如添加控制器builder.Services.AddControllers();// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbucklebuilder.Services.AddEndpointsApiExplorer();builder.Services.AddSwaggerGen();var app = builder.Build();// Configure the HTTP request pipeline.if (app.Environment.IsDevelopment()){    app.UseSwagger();    app.UseSwaggerUI();}app.UseHttpsRedirection();

请将替换为您的客户端ID,将https://api.asgardeo.io/t//oauth2/token/.well-known/openid-configuration替换为您的外部授权服务器的OpenID Connect发现文档地址。

2. 配置认证与授权中间件

在请求处理管道中,必须按照正确的顺序添加认证和授权中间件。UseAuthentication()负责验证请求的凭据(即JWT令牌),而UseAuthorization()则根据验证结果和端点上定义的授权策略来决定是否允许访问。

琅琅配音 琅琅配音

全能AI配音神器

琅琅配音 208 查看详情 琅琅配音

// ... (之前的代码)app.UseHttpsRedirection();// 启用认证中间件,它会尝试解析并验证传入请求中的JWT令牌。app.UseAuthentication();// 启用授权中间件,它会根据已认证用户的身份和策略来决定访问权限。app.UseAuthorization();// 映射控制器路由,确保在认证和授权之后执行。app.MapControllers();app.Run();

重要提示: UseAuthentication()、UseAuthorization()和MapControllers()的顺序至关重要。认证必须在授权之前发生,而路由映射则应在两者之后,以确保所有请求都能经过认证和授权检查。

3. 保护API端点

最后,通过在控制器或特定的API方法上应用[Authorize]属性,即可轻松保护您的API端点。当请求到达带有此属性的端点时,如果没有有效的JWT令牌或令牌验证失败,ASP.NET Core将返回401 Unauthorized响应。

using Microsoft.AspNetCore.Authorization;using Microsoft.AspNetCore.Mvc;namespace YourAppName.Controllers{    [ApiController]    [Route("[controller]")]    public class WeatherForecastController : ControllerBase    {        private static readonly string[] Summaries = new[]        {            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"        };        private readonly ILogger _logger;        public WeatherForecastController(ILogger logger)        {            _logger = logger;        }        [HttpGet(Name = "GetWeatherForecast")]        public IEnumerable Get()        {            return Enumerable.Range(1, 5).Select(index => new WeatherForecast            {                Date = DateTime.Now.AddDays(index),                TemperatureC = Random.Shared.Next(-20, 55),                Summary = Summaries[Random.Shared.Next(Summaries.Length)]            })            .ToArray();        }        // 添加一个受保护的私有端点        [HttpGet]        [Route("Private")] // 定义该私有端点的路由        [Authorize] // 应用Authorize属性,表示此端点需要认证        public IActionResult Private()        {            // 只有经过认证的用户才能访问此端点            return Ok(new            {                Message = "Hello from a private endpoint. You are authorized!"            });        }    }}

现在,当客户端向/WeatherForecast/Private端点发送请求时,必须在Authorization请求头中包含一个有效的Bearer JWT令牌,否则请求将被拒绝。

注意事项

外部授权服务器配置: 确保您的外部授权服务器(如AWS Cognito、Asgardeo、Auth0等)已正确配置,并且其OpenID Connect发现文档(/.well-known/openid-configuration)可公开访问。客户端类型: 本教程提供的解决方案适用于那些不涉及客户端密钥(Client Secret)的应用场景,例如单页应用(SPA)或移动应用。对于需要客户端密钥的保密客户端(Confidential Client),AddJwtBearer的配置可能需要额外的参数,例如通过Authority直接指定颁发者,或者通过HttpClient配置来处理密钥交换。令牌验证参数: MetadataAddress会自动获取大部分必要的验证参数。然而,如果您的需求特殊,可以通过TokenValidationParameters属性进行更细粒度的控制,例如强制验证颁发者(Issuer)、自定义时钟偏移(Clock Skew)等。错误处理: 对于认证失败的情况,ASP.NET Core默认会返回401 Unauthorized。您可以根据需要实现自定义的错误处理逻辑,例如通过options.Events来捕获认证失败事件。策略授权: [Authorize]属性除了可以简单地要求认证外,还可以结合策略(Policies)进行更复杂的授权控制,例如要求用户拥有特定的角色或声明。

总结

通过上述简洁的配置,您可以在C# .NET应用程序中快速构建一个纯资源服务器,实现基于JWT Bearer令牌的REST API安全。这种方法与Spring Boot中spring-boot-starter-oauth2-resource-server的理念高度一致,允许开发者专注于业务逻辑,而将令牌验证的复杂性交由框架和外部授权服务器处理。这极大地简化了API安全实现的流程,提高了开发效率和系统的可维护性。

以上就是C# .NET中基于JWT和外部授权服务器的REST API安全配置指南的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/217348.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
Intel未来4年CPU路线图曝光:100核不是梦 AMD迎来致命一击
上一篇 2026年9月27日 17:30:54
SQL窗口函数的入门与进阶:解析SQL窗口函数的强大功能
下一篇 2025年11月10日 19:26:51

相关推荐

  • Codename One:实现安全的数字密码输入框

    Codename One:实现安全的数字密码输入框Codename One:实现安全的数字密码输入框Codename One:实现安全的数字密码输入框Codename One:实现安全的数字密码输入框

    本文详细介绍了在Codename One中创建既能接受纯数字输入又能进行密码遮罩的文本输入框的方法。通过使用位或运算符(|)组合TextArea.NUMERIC和TextArea.PASSWORD约束,可以有效地实现这一需求,避免了链式调用constraint()的常见误区,从而提升用户体验和输入安…

    2026年9月27日 • 用户投稿
    000
  • Java Swing GUI:构建交互式逻辑门(AND门示例)

    Java Swing GUI:构建交互式逻辑门(AND门示例)Java Swing GUI:构建交互式逻辑门(AND门示例)Java Swing GUI:构建交互式逻辑门(AND门示例)Java Swing GUI:构建交互式逻辑门(AND门示例)

    本文详细介绍了如何使用Java Swing构建一个简单的AND逻辑门GUI应用。通过结合JCheckBox作为输入和JLabel作为视觉输出,并利用ChangeListener监听组件状态变化,实现当两个复选框都被选中时显示“绿色”,否则显示“红色”的功能。教程涵盖了组件创建、事件监听以及将自定义面…

    2026年9月27日 • 用户投稿
    100
  • Java Swing 实现带复选框和图像的逻辑门

    Java Swing 实现带复选框和图像的逻辑门Java Swing 实现带复选框和图像的逻辑门Java Swing 实现带复选框和图像的逻辑门Java Swing 实现带复选框和图像的逻辑门

    本文介绍了如何使用 Java Swing 创建一个简单的 AND 逻辑门 GUI,该 GUI 包含两个复选框和一个图像。当两个复选框都被选中时,图像变为绿色;否则,图像变为红色。我们将使用 JCheckBox、JLabel 和 ChangeListener 来实现这一功能,并提供完整的代码示例。 创…

    2026年9月27日 • 用户投稿
    000
  • sublime怎么实现vim模式_sublime Vim模式配置教程

    sublime怎么实现vim模式_sublime Vim模式配置教程sublime怎么实现vim模式_sublime Vim模式配置教程sublime怎么实现vim模式_sublime Vim模式配置教程sublime怎么实现vim模式_sublime Vim模式配置教程

    启用Vintage模式可在Sublime Text中实现Vim操作:1. 在设置中移除”Ignored_packages”里的”Vintage”以激活;2. 按Esc进入命令模式,支持hjkl移动、dd删除、yy复制、p粘贴等快捷键;3. 可通过自定义…

    2026年9月27日 • 用户投稿
    100
  • 解决Spring REST API 406 Not Acceptable错误

    解决Spring REST API 406 Not Acceptable错误解决Spring REST API 406 Not Acceptable错误解决Spring REST API 406 Not Acceptable错误解决Spring REST API 406 Not Acceptable错误

    本文旨在帮助开发者解决在使用Spring REST API时遇到的“406 Not Acceptable”错误。该错误通常表示服务器无法找到客户端可接受的表示形式。我们将详细介绍错误的原因、解决方案,并通过示例代码演示如何配置produces属性来指定API的响应类型,确保客户端能够正确接收和处理数…

    2026年9月27日 • 用户投稿
    000
  • Java:子类如何在不修改父类的情况下,通过重写方法间接利用父类私有成员

    Java:子类如何在不修改父类的情况下,通过重写方法间接利用父类私有成员Java:子类如何在不修改父类的情况下,通过重写方法间接利用父类私有成员Java:子类如何在不修改父类的情况下,通过重写方法间接利用父类私有成员Java:子类如何在不修改父类的情况下,通过重写方法间接利用父类私有成员

    在Java中,当子类需要在不修改父类的前提下,利用父类的私有成员时,直接访问是不允许的。本教程将展示如何通过调用父类的公共或保护方法(例如super.toString()),来间接利用父类内部已处理过的私有数据,尤其适用于重写方法并在此基础上扩展功能的情景。 Java封装性与私有成员:理解限制 ja…

    2026年9月27日 • 用户投稿
    000
  • Java中HashMap基本使用方法

    HashMap是Java中基于哈希表实现的键值对存储结构,属于java.util包,允许null键和null值,不保证顺序;通过put()添加元素,get()获取值,支持containsKey、remove、size等操作,并可使用keySet、values、entrySet遍历;多线程环境下不安全…

    2026年9月27日
    000
  • HTML表单动态必填字段:基于其他字段内容的条件校验

    本文将指导您如何使用JavaScript实现HTML表单中字段的条件必填校验。当一个字段(如“姓名”)有值时,另一个字段(如“位置”)才变为必填项,从而提升用户体验和数据准确性。教程将提供详细的HTML和JavaScript代码示例,并解释其工作原理,确保您能轻松掌握这种实用的前端验证技术。 在构建…

    2026年9月27日
    100
  • 算法科普——运动学LMPC和动力学LMPC之间的区别与联系

    算法科普——运动学LMPC和动力学LMPC之间的区别与联系算法科普——运动学LMPC和动力学LMPC之间的区别与联系算法科普——运动学LMPC和动力学LMPC之间的区别与联系算法科普——运动学LMPC和动力学LMPC之间的区别与联系

    在上一期的算法科普中,我已经探讨了lmpc的发展历程。然而,上一期并未深入探讨lmpc的各种分支,因此本期将重点介绍两种运动学层面的lmpc控制器和一种动力学层面的lmpc控制器。 一种常见的运动学层面的LMPC控制器的预测模型是直接对运动学模型进行雅克比线性化处理,如[1]中所述: 另一种运动学层…

    2026年9月27日 • 用户投稿
    000
  • 2026年发售? 据曝《奇异人生:双重曝光》续作开发中

    2026年发售? 据曝《奇异人生:双重曝光》续作开发中2026年发售? 据曝《奇异人生:双重曝光》续作开发中2026年发售? 据曝《奇异人生:双重曝光》续作开发中2026年发售? 据曝《奇异人生:双重曝光》续作开发中

    据最新消息,史克威尔艾尼克斯(SE)正与Deck Nine Games携手推进《奇异人生:双重曝光》的续作开发工作,这款章节式叙事冒险游戏的新篇章已悄然进入制作阶段。 Deck Nine Games的首席动画师David Blanchette以及过场动画设计师Kyle Norlander,近期在他们…

    2026年9月27日 • 用户投稿
    400
  • Java中高并发数据库同步与任务处理教程

    Java中高并发数据库同步与任务处理教程Java中高并发数据库同步与任务处理教程Java中高并发数据库同步与任务处理教程Java中高并发数据库同步与任务处理教程

    本文旨在探讨Java应用中处理高并发数据库操作的有效策略,尤其针对大量数据行的计算与状态更新场景。我们将介绍如何利用ExecutorService和任务对象实现并发处理,并通过数据库连接池优化资源管理。重点关注数据库层面的并发控制机制,如事务和行级锁,以确保数据一致性和系统性能,并提供实际的代码示例…

    2026年9月27日 • 用户投稿
    100
  • Java高并发数据库同步处理:高效任务调度与连接管理实践

    Java高并发数据库同步处理:高效任务调度与连接管理实践Java高并发数据库同步处理:高效任务调度与连接管理实践Java高并发数据库同步处理:高效任务调度与连接管理实践Java高并发数据库同步处理:高效任务调度与连接管理实践

    本文深入探讨了在Java应用中处理海量数据并发同步的策略。通过将数据库操作封装为独立任务,结合ExecutorService进行高效调度,并利用数据库连接池(如HikariCP)优化资源管理,同时强调了数据库层面事务和锁机制的重要性。文章提供了实现并发处理、标记已消费行以及确保系统高性能和数据一致性…

    2026年9月27日 • 用户投稿
    100
  • 告别繁琐构造函数:使用建造者模式优化Java对象创建

    告别繁琐构造函数:使用建造者模式优化Java对象创建告别繁琐构造函数:使用建造者模式优化Java对象创建告别繁琐构造函数:使用建造者模式优化Java对象创建告别繁琐构造函数:使用建造者模式优化Java对象创建

    本文针对Java中处理多个可选参数时,传统构造函数组合繁琐的问题,详细介绍了建造者模式(Builder Pattern)。该模式通过分阶段构建对象,避免了大量参数构造函数和重复组合,提升了代码的可读性和可维护性。文章将通过代码示例深入解析建造者模式的实现原理与优势,并提供实际应用指导。 传统构造函数…

    2026年9月27日 • 用户投稿
    200
  • INSERT INTO插入数据时:如何避免列名缺失导致的语法错误?

    INSERT INTO插入数据时:如何避免列名缺失导致的语法错误?INSERT INTO插入数据时:如何避免列名缺失导致的语法错误?INSERT INTO插入数据时:如何避免列名缺失导致的语法错误?INSERT INTO插入数据时:如何避免列名缺失导致的语法错误?

    避免insert语句列名缺失错误的核心方法有:1.显式指定列名,确保即使表结构变化时语句仍有效;2.使用orm框架如sqlalchemy或hibernate,自动映射数据模型与数据库表;3.结合数据库迁移工具如flyway管理结构变更;4.编写单元测试验证sql语句的正确性;5.采用预编译语句提升安…

    2026年9月27日 • 用户投稿
    200
  • 获取父级 Option Group 的文本标签

    获取父级 Option Group 的文本标签获取父级 Option Group 的文本标签获取父级 Option Group 的文本标签获取父级 Option Group 的文本标签

    本文介绍了如何使用 JavaScript 获取 HTML 元素中选定 标签的父级 标签的文本标签。重点在于理解 closest() 方法的行为,以及嵌套 标签可能带来的问题,并提供替代方案以实现所需功能。 理解 closest() 方法 在 JavaScript 中,closest() 方法用于查找…

    2026年9月27日 • 用户投稿
    100
  • 文本动画的类选择器应用与优化

    文本动画的类选择器应用与优化文本动画的类选择器应用与优化文本动画的类选择器应用与优化文本动画的类选择器应用与优化

    本文详细介绍了如何将基于ID的文本动画转换为基于类的实现,以支持在多个HTML元素上复用同一动画效果。通过JavaScript动态生成带有自定义CSS变量的标签,并结合CSS @keyframes动画,实现了可灵活应用于页面中任意指定元素的波浪式文本动画,并提供了两种优化方案。 1. 问题背景与目标…

    2026年9月27日 • 用户投稿
    100
  • 在WildFly中集成EJB与JAX-WS:解决部署与访问难题

    在WildFly中集成EJB与JAX-WS:解决部署与访问难题在WildFly中集成EJB与JAX-WS:解决部署与访问难题在WildFly中集成EJB与JAX-WS:解决部署与访问难题在WildFly中集成EJB与JAX-WS:解决部署与访问难题

    本文详细介绍了在WildFly应用服务器上,将EJB(Enterprise JavaBeans)与JAX-WS(Java API for XML Web Services)项目整合到EAR(Enterprise Archive)中的实践。教程涵盖了多模块Maven项目结构、依赖管理、以及如何解决部署…

    2026年9月27日 • 用户投稿
    100
  • Grafana 随笔:安装篇

    Grafana 随笔:安装篇Grafana 随笔:安装篇Grafana 随笔:安装篇Grafana 随笔:安装篇

    grafana 是一款功能强大的开源可视化工具,适合与 zabbix、prometheus 等监控软件配合使用,生成美观且便捷的图表。 前言 前提条件 在开始安装之前,请确保已关闭 Selinux 和防火墙。 sed -i ‘s/SELINUX=enforcing/SELINUX=disabled/…

    2026年9月27日 • 用户投稿
    200
  • 在Java中如何优化线程池大小

    线程池大小应根据任务类型和运行环境优化:CPU密集型设为CPU核心数+1,I/O密集型可设为核心数2~4倍;避免无界队列,选用有界队列并配置合理拒绝策略;通过监控活跃线程、队列长度等指标动态调优;优先使用ThreadPoolExecutor显式配置,避免Executors默认风险。 线程池大小的设置…

    2026年9月27日
    100
  • Java循环中条件判断消息重复输出的优化策略

    Java循环中条件判断消息重复输出的优化策略Java循环中条件判断消息重复输出的优化策略Java循环中条件判断消息重复输出的优化策略Java循环中条件判断消息重复输出的优化策略

    本文探讨了Java循环中因条件判断逻辑不当导致重复输出消息的常见问题。通过引入布尔标志位或利用循环的早期退出机制,可以有效管理循环内的状态,确保在遍历集合时,根据匹配结果只输出一次准确的成功或失败信息,从而提高程序的逻辑清晰度和用户体验。 问题分析:循环中的重复判断 在处理集合数据时,我们经常需要遍…

    2026年9月27日 • 用户投稿
    100

发表回复

登录后才能评论
关注微信