如何在.NET Core 2.0中验证OWIN OAuth 3.0.0颁发的令牌
如何在.NET Core 2.0中验证并读取Microsoft.Owin.Security.OAuth 3.0.0颁发的machineKey保护令牌
问题背景梳理
你目前的架构是这样的:
- 授权服务器基于.NET 4.5.1构建,用
Microsoft.Owin.Security.OAuth 3.0.0组件,令牌默认靠machineKey保护(AccessTokenFormat为原生默认格式) - 已有多个.NET 4.5.1的资源服务器,通过在web.config里共享相同
machineKey来验证令牌
现在要新增.NET Core 2.0应用,需要兼容现有令牌,但无法修改授权服务器添加DataProtector,得找用现有machineKey解码OWIN令牌的可行方案。
官方给出的结论
针对这个跨框架令牌兼容的问题,官方目前没有内置支持计划,给出的方向是:
关闭此问题,因为暂无支持计划。您可以使用Identity Server等第三方令牌服务器来生成兼容两种系统的令牌,或为ASP.NET Core编写自定义代码以处理OWIN/Katana风格的令牌。
简单来说,要么换一套能跨框架生成令牌的服务,要么自己写自定义逻辑适配。
临时可行方案:授权服务器侧动态切换令牌格式
通过Autofac.Integration.Owin包配合OAuthAuthorizationServerMiddleware,在授权服务器运行时根据请求来源的资源服务器类型,返回对应兼容格式的令牌。以下是Autofac配置的核心实现示例:
// Autofac注册OAuth配置的核心代码 builder.Register(c => { var oAuthOptions = new OAuthAuthorizationServerOptions { // 保留原有授权服务器的基础配置(比如TokenEndpointPath、Provider等) Provider = new CustomOAuthProvider(), // 替换为自定义的动态令牌格式解析器 AccessTokenFormat = new DynamicAccessTokenFormatResolver(c.Resolve<IResourceServerDetector>()) }; return oAuthOptions; }).As<OAuthAuthorizationServerOptions>().SingleInstance(); // 自定义动态令牌格式解析器,实现跨框架兼容 public class DynamicAccessTokenFormatResolver : ISecureDataFormat<AuthenticationTicket> { private readonly IResourceServerDetector _resourceServerDetector; private readonly ISecureDataFormat<AuthenticationTicket> _originalOwinFormat; private readonly ISecureDataFormat<AuthenticationTicket> _coreCompatibleFormat; public DynamicAccessTokenFormatResolver(IResourceServerDetector detector) { _resourceServerDetector = detector; // 原有OWIN默认的machineKey保护格式 _originalOwinFormat = new TicketDataFormat(new MachineKeyDataProtector()); // 兼容.NET Core的令牌格式(这里示例用JWT,你也可以根据需求自定义) _coreCompatibleFormat = new JwtSecureDataFormat(new TokenValidationParameters { ValidIssuer = "你的授权服务器地址", ValidAudience = "资源服务器标识", IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("共享的密钥")) // 其他JWT验证参数按需配置 }); } public string Protect(AuthenticationTicket data) { // 根据请求判断资源服务器类型,返回对应格式的令牌 if (_resourceServerDetector.IsDotNetCoreResourceServer()) { return _coreCompatibleFormat.Protect(data); } // 给原有.NET 4.5.1资源服务器返回原生OWIN格式令牌 return _originalOwinFormat.Protect(data); } public AuthenticationTicket Unprotect(string protectedText) { // 授权服务器一般不需要解码自己颁发的令牌,按需实现即可 throw new NotImplementedException(); } } // 资源服务器类型检测器:通过请求特征判断是否是.NET Core应用 public interface IResourceServerDetector { bool IsDotNetCoreResourceServer(); } public class DefaultResourceServerDetector : IResourceServerDetector { private readonly IOwinContext _context; public DefaultResourceServerDetector(IOwinContext context) { _context = context; } public bool IsDotNetCoreResourceServer() { // 示例逻辑:通过自定义请求头标识判断 return _context.Request.Headers.ContainsKey("X-Resource-Server-Type") && _context.Request.Headers["X-Resource-Server-Type"] == "DotNetCore"; } }
方案说明
- 动态格式切换:通过自定义
ISecureDataFormat<AuthenticationTicket>接口实现,根据请求来源的资源服务器类型,选择返回OWIN原生格式(给.NET 4.5.1应用)还是.NET Core兼容的格式(比如JWT,给.NET Core 2.0应用) - 资源服务器识别:通过自定义检测器,利用请求头、请求路径等特征区分资源服务器类型,确保令牌格式匹配
- 兼容原有系统:完全保留原有.NET 4.5.1资源服务器的验证逻辑,同时让.NET Core应用能拿到可正常解析的令牌
这个方案的优势是不需要大规模改造现有授权服务器,只通过注入动态格式解析逻辑就能实现跨框架兼容,适合无法完全替换授权服务器的场景。
内容的提问来源于stack exchange,提问作者Alexey Gorbel
相关产品推荐
相关产品推荐

