ASP.NET Core 6.0中OpenIddict令牌认证本地IIS失效但IIS Express正常
.NET Core 6.0中OpenIddict令牌认证在IIS部署后失效的解决方法
问题描述
在.NET Core 6.0的REST/Web API中使用OpenIddict实现基于令牌的认证与授权,该功能在Visual Studio的IIS Express中可正常运行,但部署到本地IIS服务器后失效:
- IIS Express调用Token API(
POST http://localhost:5023/token,请求体为x-www-form-urlencoded格式,包含client_id、client_secret、grant_type:client_credentials)可正常获取响应令牌:{ "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IkYzNTYzRTU0OTkwNEZFOENFRjg2NkI1RjRCNjc1MDU0NzFGQjcwQjciLCJ4NXQiOiI4MVktVkprRV9venZobXRmUzJkUVZISDdjTGMiLCJ0eXAiOiJhdCtqd3QifQ.eyJzdWIiOiJrYW1hbCIsIm5hbWUiOiJrYW1hbCIsIm9pX3Byc3QiOiJrYW1hbCIsImNsaWVudF9pZCI6ImthbWFsIiwib2lfdGtuX2lkIjoiNThiYWJkODctNmFjZC00MTc2LWIxNTctMGE2YWNlMGRkMjY3IiwianRpIjoiOTBlOWNmOWItNjNjMi00MDVhLTk3ZjQtM2Q4YjQyYTEwMjI3IiwiZXhwIjoxNjc4NzkyNDY1LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUwMjMvIiwiaWF0IjoxNjc4Nzg4ODY1fQ.fj7iNpDrESf6duOIaPKEiL1wmSsMaHUVJpkEsY0LlE-4KVfplnkEtfVOXpF3B-NyEtbwEZnGKadtXMEBAs2168p8egkDe-X2Kkc1jJPv0joO_iJlcBXdT4e0kLQr-L8j3b0Cro1hw7K1FQimgwR04PIPqVOj4m4Q0xzge7-Ism5-i-JYtuIdGQNt2gfd-z_DTjIuV3zHXLv0qVGu6uv5b0aCM0EZFuzXOg_4WurqwM68I4lhHycS5KI2NiqRJnubA6de_uwjsVwzKvNOA_q5MG6XXh3xy8v_NwL4qrDPZj3mO9VXc2RZDYt4IIeASNTlpJ9e92Q89odF3ZTYrnh_yA", "token_type": "Bearer", "expires_in": 3599 } - 本地IIS服务器调用该Token API时出现500内部服务器错误,调试发现Exchange方法中
var request = HttpContext.GetOpenIddictServerRequest();返回null。
现有OpenIddict配置(Program.cs)
builder.Services.AddOpenIddict() .AddCore(options => { // Configure OpenIddict to use the EF Core stores/models. options.UseEntityFrameworkCore() .UseDbContext<OpenIDDBContext>(); }) .AddServer(options => { options .SetTokenEndpointUris("/token"); options .AllowClientCredentialsFlow(); // Encryption and signing of tokens options .AddEphemeralEncryptionKey() .AddEphemeralSigningKey() .DisableAccessTokenEncryption(); // Register scopes (permissions) //options.RegisterScopes("api"); // Register signing and encryption details options.AddDevelopmentEncryptionCertificate() .AddDevelopmentSigningCertificate(); // Register the ASP.NET Core host and configure the ASP.NET Core-specific options. options .UseAspNetCore() .EnableTokenEndpointPassthrough() .DisableTransportSecurityRequirement(); }) .AddValidation(options => { // Import the configuration from the local OpenIddict server instance. options.UseLocalServer(); // Register the ASP.NET Core host. options.UseAspNetCore(); });
修正配置与解决步骤
1. 清理证书与密钥配置冲突
当前配置同时使用临时密钥和开发证书,二者冲突且不适合IIS部署:
- 移除临时密钥配置行:
.AddEphemeralEncryptionKey().AddEphemeralSigningKey() - 替换为持久化证书配置,本地测试可使用自签名证书(替换证书名称为你的证书标识):
// 示例:使用自签名证书 options.AddSigningCertificate("CN=LocalIISAuthCert") .AddEncryptionCertificate("CN=LocalIISAuthCert");
临时密钥仅适用于IIS Express,IIS部署后应用重启会丢失密钥,导致认证流程中断。
2. 调整IIS请求处理配置
确保IIS正确转发POST表单数据,避免WebDAV模块干扰:
在项目根目录的web.config中添加/修改以下配置:
<system.webServer> <modules> <remove name="WebDAVModule" /> </modules> <handlers> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" /> </handlers> <aspNetCore processPath="dotnet" arguments=".\YourApi.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" /> </system.webServer>
- 移除WebDAV模块,防止其拦截POST请求
- 启用stdout日志,方便排查500错误的具体原因
- 使用进程内托管模式,减少跨进程请求传递的问题
3. 确认中间件顺序
确保Program.cs中中间件顺序正确,认证中间件需在授权中间件之前:
app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); // 先执行认证 app.UseAuthorization(); // 再执行授权 app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
4. 检查IIS应用池设置
- 应用池的
.NET CLR版本需设置为无托管代码,因为.NET Core应用自带运行时 - 确认应用池权限足够访问证书和数据库资源
5. 启用详细日志排查
在appsettings.json中开启OpenIddict的Debug日志,获取更详细的错误信息:
"Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", "OpenIddict": "Debug" } }
查看IIS的stdout日志或应用日志,定位500错误的具体堆栈信息。
内容的提问来源于stack exchange,提问作者Gags
相关产品推荐
相关产品推荐

