如何让.NET资源API兼容现有PHP OAuth 2.0授权服务器的Bearer Token
我来给你梳理下怎么解决这个问题——你现在有一套自定义的PHP OAuth2授权服务器(采用Bearer Token认证),要开发.NET资源API来复用这些Token,之前看到的示例都是.NET自家授权+资源服务器搭配的场景,提到要共享机器密钥,但其实不用这么麻烦,核心得看你的PHP服务器颁发的是哪种Token,分两种情况处理:
这是最常见的情况,JWT是自包含的Token,里面自带用户信息、过期时间等,签名用的是非对称加密(比如RS256),.NET资源服务器只需要用公钥验证签名就行,完全不需要和PHP服务器共享密钥。步骤如下:
1. 拿到PHP授权服务器的公钥
如果你的PHP服务器用RS256这类非对称算法签JWT,肯定有对应的公钥(一般是PEM格式)。要么直接从PHP开发那边要,要么如果授权服务器有JWKS(JSON Web Key Set)端点(专门对外暴露公钥的接口),可以让.NET自动去拉取。
2. 在.NET资源API里配置JWT认证
先装NuGet包:
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
然后在Program.cs(如果是老版本.NET就是Startup.cs)里配置认证逻辑:
var builder = WebApplication.CreateBuilder(args); // 添加JWT认证服务 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { // 配置授权服务器地址,用来验证Token的签发者(Issuer) options.Authority = "https://你的PHP授权服务器域名"; // 如果授权服务器没有JWKS端点,就手动填公钥 // options.TokenValidationParameters = new TokenValidationParameters // { // ValidateIssuer = true, // ValidIssuer = "https://你的PHP授权服务器域名", // ValidateAudience = true, // ValidAudience = "你的.NET资源API的受众标识(和PHP服务器配置的一致)", // ValidateLifetime = true, // IssuerSigningKey = new JsonWebKey("复制过来的PHP服务器公钥内容") // }; // 如果有JWKS端点,只需要配置基础验证参数就行,.NET会自动去拿公钥 options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidAudience = "你的.NET资源API的受众标识" }; }); // 启用授权服务 builder.Services.AddAuthorization(); builder.Services.AddControllers(); var app = builder.Build(); // 记得把认证和授权中间件加上,顺序不能错 app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
3. 测试验证
客户端请求的时候,在请求头里带Authorization: Bearer <你的Token>,.NET会自动帮你验证JWT的签名、过期时间、签发者和受众,验证过了就能在控制器里通过User.Claims拿到用户信息了。
这种Token只是一个字符串标识符,本身不带任何用户信息,资源服务器得调用授权服务器的Token Introspection标准接口(RFC7662定义的)去验证Token是否有效、有没有权限访问当前资源。这种也不需要共享密钥,步骤如下:
1. 确认PHP服务器支持Introspection端点
先跟PHP开发确认,他们的授权服务器有没有实现这个接口,一般地址是https://你的PHP授权服务器域名/oauth/introspect,而且这个接口需要资源服务器用自己的客户端ID和密钥去调用(相当于资源服务器也是授权服务器的一个客户端)。
2. 在.NET资源API里配置Token验证
用IdentityModel提供的专门处理引用式Token的包,先装NuGet:
Install-Package IdentityModel.AspNetCore.OAuth2Introspection
然后在Program.cs里配置:
var builder = WebApplication.CreateBuilder(args); // 添加OAuth2 Introspection认证 builder.Services.AddAuthentication(OAuth2IntrospectionDefaults.AuthenticationScheme) .AddOAuth2Introspection(options => { // 配置Introspection接口地址 options.IntrospectionEndpoint = "https://你的PHP授权服务器域名/oauth/introspect"; // 资源服务器的客户端ID和密钥(在PHP授权服务器那边提前注册好的) options.ClientId = "你的.NET资源API的客户端ID"; options.ClientSecret = "你的.NET资源API的客户端密钥"; // 可选:配置验证规则,比如验证受众 options.TokenValidationParameters = new TokenValidationParameters { ValidateAudience = true, ValidAudience = "你的.NET资源API的受众标识" }; }); builder.Services.AddAuthorization(); builder.Services.AddControllers(); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
3. 测试验证
同样,客户端请求带Authorization: Bearer <引用式Token>,.NET会自动调用PHP的Introspection接口去验证Token,没问题的话就可以访问资源了。
- 别搞混对称和非对称加密:之前看到的.NET示例要共享机器密钥,是因为他们用的是HS256这类对称加密的JWT,这种才需要共享密钥。但只要你的PHP服务器用的是RS256这种非对称加密,只用公钥就行,绝对不能把私钥给出去。
- Issuer和Audience必须匹配:不管是哪种Token,都得确保.NET这边配置的签发者(Issuer)和受众(Audience)跟PHP服务器颁发的Token里的完全一致,不然验证肯定失败。
- 必须用HTTPS:Bearer Token是通过HTTP头传的,不用HTTPS的话很容易被窃取,这个是硬性要求。
内容的提问来源于stack exchange,提问作者D Lo

