You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。解决方法有两种:
    1. 在站点功能视图中禁用WebDAV模块;
    2. 在项目的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中添加角色的用法是否正确

这个用法基本没问题,但有几个细节需要优化:

  1. 避免同步阻塞异步方法:代码里用_userManager.GetRolesAsync(user).Result同步调用异步方法,容易引发死锁,建议改成异步调用:
    var roles = await _userManager.GetRolesAsync(user);
    var roleName = roles.FirstOrDefault() ?? string.Empty;
    
  2. 空值处理:如果用户没有任何角色,FirstOrDefault()会返回null,直接调用.ToString()会抛出空引用异常,必须加空值判断。
  3. 标准角色声明键:除了ClaimTypes.Role,也可以用JwtRegisteredClaimNames.Role,这是JWT标准的角色声明键,两者在授权验证中效果一致,但后者更贴合JWT规范。

内容的提问来源于stack exchange,提问作者ashkufaraz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 01:12:05