ASP.NET Core MVC 身份功能在发布到服务器时不起作用
Posted
技术标签:
【中文标题】ASP.NET Core MVC 身份功能在发布到服务器时不起作用【英文标题】:ASP.NET Core MVC Identity features not working when published to server 【发布时间】:2021-07-22 13:58:07 【问题描述】:我有一个 ASP.NET Core MVC Web 应用程序,它使用 Entity Framework 和 Microsoft Identity 作为用户帐户。我能够在调试中运行应用程序并创建帐户/登录等,但是,当发布到 iis 时,我收到以下错误:
Error Message
有问题的代码在下面的 _Layout.cshtml 中,据我所知,它没有像在调试中那样实现用户身份。
_Layout.cshtml
@using Microsoft.AspNetCore.Identity
@using MyApp.Areas.Identity.Data
@inject UserManager<MyAppUser> userManger
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MyApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<div style="height:30px; margin-top:0px;">
<img class="navbar-brand" style="height:auto; width:auto; max-height:100%; max-width:100%;" src="~/images/AASLogoDarkMinimal.png" />
</div>
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">My App</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<partial name="_LoginPartial.cshtml" />
<ul class="navbar-nav flex-grow-1">
@if (User.Identity.IsAuthenticated)
var user = await userManger.GetUserAsync(User);
var rolesArray = userManger.GetRolesAsync(user).Result;
if (rolesArray.Contains("Administrator") || rolesArray.Contains("Sales Administrator"))
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle text-info" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Admin Tools
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
@if (rolesArray.Contains("Administrator"))
<a type="button" class="dropdown-item btn btn-info btn-sm" asp-controller="User" asp-action="Index">User Management</a>
@if (rolesArray.Contains("Sales Administrator"))
<a type="button" class="dropdown-item btn btn-info btn-sm" asp-controller="User" asp-action="Index">Price Management</a>
</div>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© @DateTime.Now.Year - My Application
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
可能与 IdentityHostingStartup.cs 有关吗?
IdentityHostingStartup.cs
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MyApp.Areas.Identity.Data;
using MyApp.Data;
[assembly: HostingStartup(typeof(MyApp.Areas.Identity.IdentityHostingStartup))]
namespace MyApp.Areas.Identity
public class IdentityHostingStartup : IHostingStartup
public void Configure(IWebHostBuilder builder)
builder.ConfigureServices((context, services) =>
services.AddDbContext<MyAppAuthDbContext>(options =>
options.UseSqlServer(
context.Configuration.GetConnectionString("MyAppAuthDbContextConnection")));
services.AddDefaultIdentity<MyAppUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<MyAppAuthDbContext>();
);
Startup.cs
public class Startup
public Startup(IConfiguration configuration)
Configuration = configuration;
public IConfiguration Configuration get;
public void ConfigureServices(IServiceCollection services)
services.AddDbContext<DbContextSQLIdentity>(options => options.UseSqlServer(Configuration.GetConnectionString("SQLIdentDB")));
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);
services.AddControllersWithViews().AddRazorRuntimeCompilation();
services.AddRazorPages();
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
endpoints.MapControllerRoute(
name: "default",
pattern: "controller=Home/action=Index/id?");
endpoints.MapRazorPages();
);
【问题讨论】:
您登录的用户是否有关联的角色? 我无法进入登录屏幕,这是应用程序加载时出现的错误。我在 Home 控制器索引上有 [Authorize],它应该会提示返回登录屏幕。这是调试中发生的情况,但是当发布到服务器时,它会失败。 【参考方案1】:我猜这行:
var rolesArray = userManger.GetRolesAsync(user).Result;
返回 null,因此使用 .Contains 的下一行将因 NRE 而失败。
这表明您的登录用户没有角色。
顺便说一句,在 Task
上调用 .Result
不是一种好的做法,有时会导致任务锁定。
【讨论】:
我还没到可以登录用户的阶段。我在主控制器索引上有 [Authorize],它会提示登录屏幕显示(即在调试中)。发布时,它在第一个障碍时失败并返回错误。感谢您对 .Result 的关注。那是来自复制/粘贴解决方案。 应用启动时,User.Identity.IsAuthenticated() 应该返回false,但看起来返回true,允许嵌套代码运行并导致错误。 我发现了问题!我需要在服务器上的 IIS 中禁用 Windows 身份验证并启用匿名身份验证。【参考方案2】:我发现了问题!我需要在服务器上的 IIS 中禁用 Windows 身份验证并启用匿名身份验证。
【讨论】:
以上是关于ASP.NET Core MVC 身份功能在发布到服务器时不起作用的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core MVC:设置身份 cookie 过期
从 ASP.NET Core 1.1 MVC 迁移到 2.0 后,自定义 cookie 身份验证不起作用