我成功地将我的应用程序从 MVC4-EF5 更新到 MVC5-EF6。
然后我将我的数据库从 Simplemebership 迁移到 Identity 2.0。
我可以登录,但 User.IsInRole 总是返回 false。所有正确的表 AspNetUsers、AspNetRoles、AspNetUserRoles、AspNetLogins 和 AspNetClaims 都已创建,所有列的拼写和类型都正确,并且已使用 SimpleMembership 表中的数据(已删除)填充它们。
我有一个用户“MyUser”,它在 AspNetUsers 表中的 Id = 2 和一个角色“XYZ”,它在 AspNetRoles 表中的 Id = 2,用户 2 映射到 AspNetUserRoles 表中的角色 2。
以“我的用户”身份登录时
var user = _db.Users.SingleOrDefault(u => u.UserName == User.Identity.Name);
用户确实设置为“MyUser”,但
User.IsInRole("XYZ")
返回假。
我添加了一个测试变量 ,
var testrole = Roles.GetRolesForUser();
当在调试中检查 testrole 时,它返回一个空字符串数组 {string[0]}。User.IsInRole("XYZ")
从立即窗口运行返回 false。
我已经阅读了我可以找到的关于 Identity、Identity 2.0 以及从 SimpleMembership 和 Identity 1.0 迁移的所有文档,但我找不到任何实现要求(除了我在发布的代码中所做的),我错过了制作 Identity工作(从那时起它就在某种程度上工作了登录工作)。
我已经使用 Identity 2.0 的可扩展性挂钩来为我的主键实现 INT。
WebSecConfig.cs:(从 Global.asax.cs 调用)(删除了更新代码:1)
using WebMatrix.WebData;
namespace MyApplication
{
public static class WebSecConfig
{
public static void RegisterWebSec()
{
WebSecurity.InitializeDatabaseConnection
("MyApplication", "AspNetUsers", "Id", "UserName", autoCreateTables: true);
}
}
}
应用用户:
public class ApplicationUser : IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim>
{
[StringLength(15)]
public new string UserName { get; set; }
public int AcId { get; set; }
public int LcId { get; set; }
}
public class CustomRole : IdentityRole<int, CustomUserRole>
{
public CustomRole() { }
public CustomRole(string name) { Name = name; }
}
public class CustomUserRole : IdentityUserRole<int> { }
public class CustomUserClaim : IdentityUserClaim<int> { }
public class CustomUserLogin : IdentityUserLogin<int> { }
身份数据库上下文:
public class MyDb : IdentityDbContext<ApplicationUser, CustomRole, int, CustomUserLogin, CustomUserRole, CustomUserClaim>
{
public MyDb() : base("MyApplication") { }
// public virtual DbSet<UserProfiles> Users { get; set; }
public virtual DbSet<MyTable> MyTables { get; set; } // properties marked virtual for Mocking override
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
账户控制人:
[RequireHttps]
[Authorize]
public class AccountController : Controller
{
private readonly IUserService _userService;
public UserManager<ApplicationUser, int> UserManager { get; private set; }
public AccountController()
: this(new UserService(), new UserManager<ApplicationUser, int>(new UserStore<ApplicationUser, CustomRole, int, CustomUserLogin, CustomUserRole, CustomUserClaim>new MyDb()))) { }
public AccountController(IUserService userService, UserManager<ApplicationUser, int> userManager)
{ _userService = userService; UserManager = userManager; }
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login() { return View(); }
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginVm vM)
{
if (ModelState.IsValid)
{
var user = UserManager.Find(vM.UserName, vM.Password);
if (user != null)
{
FormsAuthentication.SetAuthCookie(user.UserName, false);
return RedirectToAction("UserRouting", "Home");
}
}
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(vM);
}
家庭控制器:
using System;
using System.Web.Mvc;
using MyApplication.Models;
using System.Linq;
using System.Web.Security;
namespace MyApplication.Controllers
{
[Authorize]
public class HomeController : Controller
{
private readonly MyDb _db = new MyDb();
public ActionResult UserRouting()
{
var user = _db.Users.SingleOrDefault(u => u.UserName == User.Identity.Name);
var testrole = Roles.GetRolesForUser(); // for testing, remove from production
if (User.IsInRole("XYZ")) { // mycode }
...
}
}
迁移脚本:(以SimpleMembershipToIdentityMigration.sql为模型,针对 Identity 2.0 和 INT 主键进行了修改)
/****** Object: Table [dbo].[AspNetRoles] Script Date: 4/30/14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF OBJECT_ID('dbo.AspNetUserRoles', 'U') IS NOT NULL
DROP TABLE [dbo].[AspNetUserRoles]
GO
--IF OBJECT_ID('dbo.AspNetUserLogins', 'U') IS NOT NULL
-- DROP TABLE [dbo].[AspNetUserLogins]
--GO
IF OBJECT_ID('dbo.AspNetUserClaims', 'U') IS NOT NULL
DROP TABLE [dbo].[AspNetUserClaims]
GO
IF OBJECT_ID('dbo.AspNetRoles', 'U') IS NOT NULL
DROP TABLE [dbo].[AspNetRoles]
GO
IF OBJECT_ID('dbo.AspNetUsers', 'U') IS NOT NULL
DROP TABLE [dbo].[AspNetUsers]
GO
CREATE TABLE [dbo].[AspNetUsers] (
--[Id] NVARCHAR (128) NOT NULL,
[Id] INT NOT NULL,
[UserName] NVARCHAR (15) NULL,
[AcId] INT NOT NULL,
[LcId] INT NOT NULL,
[Email] NVARCHAR (256) NULL,
[EmailConfirmed] BIT DEFAULT ((0)) NULL,
[PasswordHash] NVARCHAR (MAX) NULL,
[SecurityStamp] NVARCHAR (MAX) NULL,
[PhoneNumber] NVARCHAR (MAX) NULL,
[PhoneNumberConfirmed] BIT DEFAULT ((0)) NULL,
[TwoFactorEnabled] BIT DEFAULT ((0)) NULL,
[LockoutEndDateUtc] DATETIME NULL,
[LockoutEnabled] BIT DEFAULT ((0)) NULL,
[AccessFailedCount] INT DEFAULT ((0)) NOT NULL,
[CreateDate] DATETIME NULL,
CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE TABLE [dbo].[AspNetRoles] (
--[Id] NVARCHAR (128) NOT NULL,
[Id] INT NOT NULL,
[Name] NVARCHAR (256) NOT NULL,
CONSTRAINT [PK_dbo.AspNetRoles] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE TABLE [dbo].[AspNetUserRoles] (
-- [UserId] NVARCHAR (128) NOT NULL,
-- [RoleId] NVARCHAR (128) NOT NULL,
[UserId] INT NOT NULL,
[RoleId] INT NOT NULL,
CONSTRAINT [PK_dbo.AspNetUserRoles] PRIMARY KEY CLUSTERED ([UserId] ASC, [RoleId] ASC),
CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [dbo].[AspNetRoles] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_RoleId]
ON [dbo].[AspNetUserRoles]([RoleId] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_UserId]
ON [dbo].[AspNetUserRoles]([UserId] ASC);
GO
CREATE TABLE [dbo].[AspNetUserLogins] (
--[UserId] NVARCHAR (128) NOT NULL,
[UserId] INT NOT NULL,
[LoginProvider] NVARCHAR (128) NOT NULL,
[ProviderKey] NVARCHAR (128) NOT NULL,
CONSTRAINT [PK_dbo.AspNetUserLogins] PRIMARY KEY CLUSTERED ([UserId] ASC, [LoginProvider] ASC, [ProviderKey] ASC),
CONSTRAINT [FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_UserId]
ON [dbo].[AspNetUserLogins]([UserId] ASC);
GO
CREATE TABLE [dbo].[AspNetUserClaims] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[ClaimType] NVARCHAR (MAX) NULL,
[ClaimValue] NVARCHAR (MAX) NULL,
-- [UserId] NVARCHAR (128) NOT NULL,
[UserId] INT NOT NULL,
CONSTRAINT [PK_dbo.AspNetUserClaims] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.AspNetUserClaims_dbo.AspNetUsers_User_Id] FOREIGN KEY ([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_User_Id]
ON [dbo].[AspNetUserClaims]([UserId] ASC);
GO
INSERT INTO AspNetUsers(Id, UserName, AcId, LcId, PasswordHash, SecurityStamp, CreateDate )
SELECT UserProfile.UserId, UserProfile.UserName, UserProfile.BaId, UserProfile.OfcId,
webpages_Membership.Password, webpages_Membership.PasswordSalt, CreateDate
FROM UserProfile
LEFT OUTER JOIN webpages_Membership ON UserProfile.UserId = webpages_Membership.UserId
GO
INSERT INTO AspNetRoles(Id, Name)
SELECT RoleId, RoleName
FROM webpages_Roles
GO
INSERT INTO AspNetUserRoles(UserId, RoleId)
SELECT UserId, RoleId
FROM webpages_UsersInRoles
GO
IF OBJECT_ID('dbo.webpages_OAuthMembership', 'U') IS NOT NULL
DROP TABLE [dbo].[webpages_OAuthMembership]
GO
IF OBJECT_ID('dbo.webpages_UsersInRoles', 'U') IS NOT NULL
DROP TABLE [dbo].[webpages_UsersInRoles]
GO
IF OBJECT_ID('dbo.webpages_Roles', 'U') IS NOT NULL
DROP TABLE [dbo].[webpages_Roles]
GO
IF OBJECT_ID('dbo.UserProfile', 'U') IS NOT NULL
DROP TABLE [dbo].[UserProfile]
GO
IF OBJECT_ID('dbo.webpages_Membership', 'U') IS NOT NULL
DROP TABLE [dbo].[webpages_Membership]
GO
IF OBJECT_ID('dbo.__MigrationHistory', 'U') IS NOT NULL
DROP TABLE [dbo].[__MigrationHistory]
GO
我是否错过了配置 Identity 2.0 的内容,或者这是 Identity 2.0 中的错误?
更新 1:
删除了对 WebSecConfig 的 Global.asax.cs 调用。这掩盖了一个不同的问题User.IsInRole.
在主控制器用户路由操作中的 var 用户上设置断点
在调试中运行应用程序并以“MyUser”身份登录。
介入并将用户设置为“MyUser”。
进入 var testrole 并抛出'Object reference not set to an instance of an object.'
重新启动并以“MyUser”身份再次登录。
介入并将用户设置为“MyUser”。
从即时窗口输入User.IsInRole("XYZ")
并返回:
A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
A first chance exception of type 'System.Web.HttpException' occurred in System.Web.dll
A first chance exception of type 'System.Web.HttpException' occurred in System.Web.dll
A first chance exception of type 'System.Web.HttpException' occurred in System.Web.dll
并打开一个警告对话框:
HttpException was unhandled
An unhandled exception of type 'System.Web.HttpException" occurred in System.Web.dll
Additional information: Unable to connect to SQL Server database.
我的基本数据库设置是正确的,否则我将无法登录。这让我相信我运行迁移的方式存在细微差异。有谁知道我在哪里绊倒了。
更新 2: 我重构了代码和迁移脚本以使用默认的 nvarchar 作为主键,并得到与更新 1 相同的结果。
更新 3:
网络配置:
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<sectionGroup name="nwebsec">
<!-- For information on how to configure NWebsec please visit: http://nwebsec.codeplex.com/wikipage?title=Configuration -->
<section name="httpHeaderSecurityModule" type="NWebsec.Modules.Configuration.HttpHeaderSecurityConfigurationSection, NWebsec, Version=3.0.2.0, Culture=neutral, PublicKeyToken=3613da5f958908a1" requirePermission="false" />
</sectionGroup>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
</sectionGroup>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
<connectionStrings>
<add name="MyApplication" connectionString="data source=.\SqlExpress;Integrated Security=SSPI;MultipleActiveResultSets = true;initial catalog=MyDb" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="PreserveLoginUrl" value="true" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="elmah.mvc.disableHandler" value="false" />
<add key="elmah.mvc.disableHandleErrorFilter" value="false" />
<add key="elmah.mvc.requiresAuthentication" value="true" />
<add key="elmah.mvc.IgnoreDefaultRoute" value="false" />
<add key="elmah.mvc.allowedRoles" value="Admin,CorpS" />
<!--<add key="elmah.mvc.allowedUsers" value="*" />-->
<add key="elmah.mvc.route" value="elmah" />
</appSettings>
<!--
For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.
The following attributes can be set on the <httpRuntime> tag.
<system.Web>
<httpRuntime targetFramework="4.5.1" />
</system.Web>
-->
<system.web>
<customErrors mode="Off" />
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5" useFullyQualifiedRedirectUrl="true" maxRequestLength="100000" enableVersionHeader="false" />
<!-- value is Kb, need to avoid crash with file upload of large files -->
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="15" />
</authentication>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
<!--<roleManager enabled="true" defaultProvider="simple">
<providers>
<clear />
<add name="simple" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
</providers>
</roleManager>
<membership defaultProvider="simple">
<providers>
<clear />
<add name="simple" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
</providers>
</membership>-->
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>
<sessionState cookieName="My_SessionId" />
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<modules>
<add name="NWebsecHttpHeaderSecurityModule" type="NWebsec.Modules.HttpHeaderSecurityModule, NWebsec, Version=3.0.2.0, Culture=neutral, PublicKeyToken=3613da5f958908a1" />
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
<remove name="RoleManager" />
</modules>
<httpProtocol>
<customHeaders>
<clear />
</customHeaders>
</httpProtocol>
<security>
<requestFiltering>
<hiddenSegments>
<add segment="NWebsecConfig" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.6.1.0" newVersion="5.6.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.6.1.0" newVersion="5.6.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Spatial" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.6.1.0" newVersion="5.6.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Razor" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly><assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /></dependentAssembly>
<dependentAssembly><assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" /></dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly><assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /><bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" /></dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
</dependentAssembly>
</assemblyBinding>
<!-- This prevents the Windows Event Log from frequently logging that HMAC1 is being used (when the other party needs it). -->
<legacyHMACWarning enabled="0" />
<!-- When targeting ASP.NET MVC 3, this assemblyBinding makes MVC 1 and 2 references relink
to MVC 3 so libraries such as DotNetOpenAuth that compile against MVC 1 will work with it.
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
-->
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.net>
<defaultProxy enabled="true" />
<settings>
<!-- This setting causes .NET to check certificate revocation lists (CRL)
before trusting HTTPS certificates. But this setting tends to not
be allowed in shared hosting environments. -->
<!--<servicePointManager checkCertificateRevocationList="true"/>-->
</settings>
</system.net>
<nwebsec>
<httpHeaderSecurityModule xmlns="http://nwebsec.com/HttpHeaderSecurityModuleConfig.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="NWebsecConfig/HttpHeaderSecurityModuleConfig.xsd">
<redirectValidation enabled="true"> <add allowedDestination="https://localhost/" /> </redirectValidation>
<securityHttpHeaders>
<x-Frame-Options policy="Deny" />
<strict-Transport-Security max-age="365" />
<x-Content-Type-Options enabled="true" />
</securityHttpHeaders>
</httpHeaderSecurityModule>
</nwebsec>
<elmah>
<security allowRemoteAccess="false" />
</elmah>
</configuration>
<remove name="RoleManager" />
作为MVC4-MVC5迁移的一部分,我需要添加到节点,我现在已经完成了。
现在我回到我原来的问题。User.IsInRole 始终返回 false。如果我User.IsAuthenticated
从立即窗口运行它会返回
'System.Security.Principal.IPrincipal' does not contain a definition for 'IsAuthenticated' and no extension method 'IsAuthenticated' accepting a first argument of type 'System.Security.Principal.IPrincipal' could be found (are you missing a using directive or an assembly reference?)
我能够让 Identity.UserManager.IsInRole 工作。
Home Controller:(修改为使用 UserManager)
using System;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using MyApplication.Models;
using System.Linq;
//using System.Web.Security;
namespace MyApplication.Controllers
{
[Authorize]
public class HomeController : Controller
{
private readonly MyDb _db = new MyDb();
public UserManager<ApplicationUser> UserManager { get; private set; }
public HomeController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyDb()))) { }
public HomeController(UserManager<ApplicationUser> userManager)
{ UserManager = userManager; }
public ActionResult UserRouting()
{
var user = _db.Users.SingleOrDefault(u => u.UserName == User.Identity.Name);
//var testrole = Roles.GetRolesForUser(); // for testing, remove from production
if (UserManager.IsInRole(user.Id, "XYZ")) { // mycode }
...
}
}
这表明我的数据库迁移是正确的。
我在我的应用程序的控制器、视图、自定义属性、方法和类中对 User.IsInRole 进行了数十次调用。据我了解,User.IsInRole 仍然是 MVC5-EF6 中的有效方法。如果它仍然被认为是一种有效的方法,而不是必须对这个遗留应用程序进行重大重构,我再次提出我最初的问题“为什么在 SimpleMembership 到 Identity 2.0 迁移后 User.IsInRole 失败”?
我已经在 Identity 1.0 MVC 应用程序中测试了 User.IsInRole 并且它可以工作。我将应用程序更新到 Identity 2.0,它仍然可以工作。所以我认为可以肯定地说,Identity 2.0 支持 User.IsInRole。