2014-05-02 214 views
2

我成功地將我的應用程序從MVC4-EF5更新爲MVC5-EF6。將SimpleMembership數據庫遷移到Identity 2後,User.IsInRole失敗

然後,我將數據庫從Simplemebership遷移到Identity 2.0。

我可以登錄,但User.IsInRole總是返回false。所有正確的表AspNetUsers,AspNetRoles,AspNetUserRoles,AspNetLogins和AspNetClaim已經創建,所有列的拼寫和類型都是正確的,並且它們已經被SimpleMembership表中的數據填充(已被刪除)。

我有一個AspNetUsers表中id = 2的用戶MyUser,AspNetRoles表中Id = 2的角色「XYZ」,用戶2映射到AspNetUserRoles表中的角色2。

身份登錄時 「MYUSER」

var user = _db.Users.SingleOrDefault(u => u.UserName == User.Identity.Name);
用戶不會獲得設置爲 「MYUSER」 但

User.IsInRole("XYZ")返回false。

我添加了一個測試變量, var testrole = Roles.GetRolesForUser();,當在調試中檢查testrole時,它返回一個空字符串數組{string [0]}。從立即窗口運行User.IsInRole("XYZ")返回false。

我已閱讀了關於Identity,Identity 2.0和從SimpleMembership和Identity 1.0遷移的每個文檔,並且我找不到任何實現要求(超出了我在發佈的代碼中完成的操作)錯過了使身份驗證工作(並且從登錄工作開始就在某個級別上工作)。

我已經使用Identity 2.0的可擴展性鉤子爲我的主鍵實現INT。

WebSecConfig.cs:(來自Global.asax.cs中稱爲)(移除UPDATE此代碼:1)

using WebMatrix.WebData; 

namespace MyApplication 
{ 
    public static class WebSecConfig 
    { 
    public static void RegisterWebSec() 
    { 
     WebSecurity.InitializeDatabaseConnection 
     ("MyApplication", "AspNetUsers", "Id", "UserName", autoCreateTables: true); 
    } 
    } 
} 

ApplicationUser:

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> { } 

IdentityDbContext:

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和修改身份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中的錯誤?

UPDATE 1: 刪除了Global.asax.cs對WebSecConfig的調用。這已經掩蓋一個不同的問題與在調試家庭控制器UserRouting行動
運行的應用程序對用戶變種User.IsInRole.

設置斷點,並在登錄爲「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 migrati的一部分在,我現在已經完成了。

現在我回到我原來的問題。 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工作。

首頁控制器:(改版使用的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中仍然是一個有效的方法。 如果它仍然被認爲是一種有效的方法,而不是對這個遺留應用程序進行重大重構,我再次提出我的原始問題「爲什麼User.IsInRole在SimpleMembership到Identity 2.0遷移後失敗」?

我已經在Identity 1.0 MVC應用程序中測試了User.IsInRole,它工作正常。我更新了應用程序到Identity 2.0,它仍然有效。所以我認爲可以肯定的是,Identity 2.0支持User.IsInRole。

+0

顯示您的web.config。可能會配置舊成員資格提供程序的剩餘部分,並嘗試訪問不再可用的數據庫。調用UserManager.IsInRole for ASP.NET Identity會更安全。另外檢查User.IsAuthenticated是否爲真。您應該能夠查看用戶返回的ClaimsPrincipal並查看有關角色的聲明。 –

+0

謝謝凱文。我清理了一個bug(缺少),並能夠獲得Identity.UserManager.IsInRole的工作。請參閱更新3:您已經幫助我將問題向前移動,但我仍然希望獲得User.IsInRole的工作。你的進一步想法表示讚賞 – Joe

+0

嘿,我剛剛開始將simplemembership遷移到Identity 2.0。你能指導我完成這個嗎?請 – Vivekh

回答

2

經過進一步調查後,我發現問題是我從未成功登錄,並且由於用戶未通過身份驗證,導致User.IsInRole失敗。

var user = UserManager.Find(vM.UserName, vM.Password); 

當您檢查調試user「MYUSER」已經找到,但如果你深入進一步找到UserName設置爲null。

User 
    --{System.Data.Entity.DynamicProxies.ApplicationUser_...} Identity.Models.ApplicationUser{System.Data.Entity.DynamicProxies.ApplicationUser_...} … 
     base {System.Data.Entity.DynamicProxies.ApplicationUser_...} Identity.Models.ApplicationUser {System.Data.Entity.DynamicProxies.ApplicationUser_...} 
      base {System.Data.Entity.DynamicProxies.ApplicationUser_...} Microsoft.AspNet.Identity.EntityFramework.IdentityUser … 
       base {System.Data.Entity.DynamicProxies.ApplicationUser_...} Microsoft.AspNet.Identity.EntityFramework.IdentityUser<string,Microsoft.AspNet.Identity ... 
        AccessFailedCount 0   int 
        Claims    Count = 0 System.Collections.Generic.ICollection<Microsoft.AspNet.Identity.EntityFramework.IdentityUserClaim> … 
        Email    null  string 
        EmailConfirmed  false  bool 
        Id     "2"   string 
        LockoutEnabled  false  bool 
        LockoutEndDateUtc null  System.DateTime? 
        Logins    Count = 0 System.Collections.Generic.ICollection<Microsoft.AspNet.Identity.EntityFramework.IdentityUserLogin> … 
        PasswordHash  "xxxxxx" string 
        PhoneNumber   null  string 
        PhoneNumberConfirmed false bool 
        Roles    Count = 2 System.Collections.Generic.ICollection<Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole> … 
        SecurityStamp  ""   string 
        TwoFactorEnabled false  bool 
        UserName   null  string 

ApplicationUser我覆蓋了用戶名。

[StringLength(15)] 
public new string UserName { get; set; } 

當我刪除了用戶名壓倒一切開始工作(我留下用戶名作爲NVARCHAR(15),NOT NULL)。 ApplicationUser覆蓋UserName是問題。如果您想更改nvarchar大小,您顯然只需在遷移腳本中執行此操作。

從SimpleMembrship到Identity 2.0作品的遷移。 User.IsInRole也適用於Identity 2.0。