IIS部署ASP.NET Core接口报405 Method Not Allowed错误求助
相关代码
AddIdentityServices 代码
public static IServiceCollection AddIdentityServices(this IServiceCollection services, IConfiguration config) { services.AddIdentityCore<AppUser>(opt => { opt.Password.RequireDigit = false; opt.Password.RequireNonAlphanumeric = false; opt.Password.RequireLowercase = false; }) .AddRoles<IdentityRole>() .AddEntityFrameworkStores<DataContext>() .AddSignInManager<SignInManager<AppUser>>() .AddDefaultTokenProviders(); var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["TokenKey"])); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(opt => { opt.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = key, ValidateIssuer = false, ValidateAudience = false, }; }).AddIdentityCookies(); services.AddAuthorization(opt => { }); services.AddTransient<IAuthorizationHandler, IsHostRequirementHandler>(); services.AddScoped<TokenService>(); return services; }
CreateToken 代码
public string CreateToken(AppUser user) { var role_name = _userManager.GetRolesAsync(user).Result.FirstOrDefault().ToString(); var claim = new List<Claim> { new Claim(ClaimTypes.Name, user.UserName), new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.Email, user.Email), new Claim (ClaimTypes.Role,role_name.ToString()) }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["TokenKey"])); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claim), Expires = DateAndTime.Now.AddDays(10), SigningCredentials = creds, }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); }
控制器授权代码
[Authorize(Roles = "Admin")] [HttpPut, Route("setAction")] public async Task<IActionResult> setAction(RequestVehicle requestVehicle) { return ... }
问题解答
一、IIS返回405 Method Not Allowed的原因
本地正常但部署到IIS后出现该错误,常见原因有这几个:
- PUT请求被IIS拦截:默认情况下IIS的请求筛选可能禁用了PUT方法,需进入站点的「请求筛选」设置,检查HTTP方法列表,确保PUT未被禁止。
- WebDAV模块干扰:IIS默认安装的WebDAV模块会拦截PUT请求,直接返回405。解决方法有两种:
- 在站点功能视图中禁用WebDAV模块;
- 在项目的web.config中添加配置移除WebDAV:
<system.webServer> <modules runAllManagedModulesForAllRequests="false"> <remove name="WebDAVModule" /> </modules> <handlers> <remove name="WebDAV" /> </handlers> </system.webServer>
- 路由或重写规则冲突:检查IIS的URL重写规则,确保PUT请求能正确映射到控制器的
setAction方法,没有被其他规则拦截。 - 应用池权限不足:IIS应用池的身份可能没有足够权限处理PUT请求,可尝试将应用池身份改为「LocalSystem」测试,再调整到合适的权限。
二、Claim中添加角色的用法是否正确
这个用法基本没问题,但有几个细节需要优化:
- 避免同步阻塞异步方法:代码里用
_userManager.GetRolesAsync(user).Result同步调用异步方法,容易引发死锁,建议改成异步调用:var roles = await _userManager.GetRolesAsync(user); var roleName = roles.FirstOrDefault() ?? string.Empty; - 空值处理:如果用户没有任何角色,
FirstOrDefault()会返回null,直接调用.ToString()会抛出空引用异常,必须加空值判断。 - 标准角色声明键:除了
ClaimTypes.Role,也可以用JwtRegisteredClaimNames.Role,这是JWT标准的角色声明键,两者在授权验证中效果一致,但后者更贴合JWT规范。
内容的提问来源于stack exchange,提问作者ashkufaraz
相关产品推荐
相关产品推荐

