我使用ASP.NET Identity 2.0,我想知道登录的用户是否具有角色" admin"。在我的种子方法中,我创建了3个不同的角色:
var store = new UserStore<ApplicationUser>(context);
var userManager = new ApplicationUserManager(store);
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
string roleName = "admin";
if (!roleManager.RoleExists(roleName))
{
roleManager.Create(new IdentityRole(roleName));
}
roleName = "superuser";
if (!roleManager.RoleExists(roleName))
{
roleManager.Create(new IdentityRole(roleName));
}
roleName = "user";
if (!roleManager.RoleExists(roleName))
{
roleManager.Create(new IdentityRole(roleName));
}
var user = new ApplicationUser() { Email = "nsg@gmail.com", UserName = "Niclas" };
userManager.Create(user, "123456");
userManager.AddToRole(user.Id, "Admin");
取决于用户是否是管理员,他需要在导航栏中看到不同的链接,所以我已经制作了这段代码:
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Lenio", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
@if (Roles.IsUserInRole(User.Identity.Name,"admin"))
{
<li>@Html.ActionLink("Admins", "Index", "Admins")</li>
<li>@Html.ActionLink("SuperUsers", "Index", "SuperUsers")</li>
<li>@Html.ActionLink("Users", "Index", "Users")</li>
<li>@Html.ActionLink("Areas", "Index", "Areas")</li>
<li>@Html.ActionLink("CDs", "Index", "CommunicationDevices")</li>
<li>@Html.ActionLink("Houses", "Index", "Houses")</li>
<li>@Html.ActionLink("Lendings", "Index", "Lendings")</li>
<li>@Html.ActionLink("Logs", "Index", "Logs")</li>
<li>@Html.ActionLink("Sensors", "Index", "Sensors")</li>
}
@if (User.IsInRole("user"))
{
<li>@Html.ActionLink("User", "Index", "Din bruger")</li>
}
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
@Html.Partial("_LoginPartial")
</div>
</div>
</div>
问题是,当代码到达@if (Roles.IsUserInRole(User.Identity.Name,"admin"))
部分时,我会收到{"Invalid object name 'dbo.aspnet_SchemaVersions'."}
个异常。我的数据库中没有aspnet_SchemaVersions表,我不想要它。
以下是与我拥有的身份相关的表格的图片:
db托管在azure上。
更新
DavidG发布了一个解决了初始问题的答案,但它已经解决了我无法解决的问题:
[Authorize(Roles = "admin")]
我需要能够使用此属性,但我无法获得此异常:
> [SqlException (0x80131904): Invalid object name 'dbo.aspnet_SchemaVersions'.]
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +1789294
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +5340642
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +244
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) +1691
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +275
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds) +1421
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) +177
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) +208
System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +163
System.Web.Util.SecUtility.CheckSchemaVersion(ProviderBase provider, SqlConnection connection, String[] features, String version, Int32& schemaVersionCheck) +392
System.Web.Security.SqlRoleProvider.CheckSchemaVersion(SqlConnection connection) +64
System.Web.Security.SqlRoleProvider.GetRolesForUser(String username) +753
System.Web.Security.RolePrincipal.IsInRole(String role) +9625099
System.Linq.Enumerable.Any(IEnumerable`1 source, Func`2 predicate) +146
System.Web.Mvc.AuthorizeAttribute.AuthorizeCore(HttpContextBase httpContext) +333
System.Web.Mvc.AuthorizeAttribute.OnAuthorization(AuthorizationContext filterContext) +379
System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor) +143
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__19(AsyncCallback asyncCallback, Object asyncState) +1680
System.Web.Mvc.Async.WrappedAsyncResult`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +59
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +94
System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +559
System.Web.Mvc.Controller.<BeginExecuteCore>b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState) +82
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +105
System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +588
System.Web.Mvc.Controller.<BeginExecute>b__14(AsyncCallback asyncCallback, Object callbackState, Controller controller) +47
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +65
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +139
System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +484
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState) +98
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +106
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +446
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
答案 0 :(得分:2)
此错误的原因是您的应用程序尝试首先使用旧版本的Identity进行连接。你不应该使用&#39;遗产&#39;用于管理角色的对象的版本。使用新的UserManager
和RoleManager
类。
例如:
var store = new UserStore<ApplicationUser>(context);
var userManager = new ApplicationUserManager(store);
if(userManager.IsInRole(userId, "NameOfRole")
{
//do stuff
}
要在您的视图中使用此功能,您可以创建自己的帮助程序:
namespace MyProject.MyNamespace.MyExtensions
{
public static class IdentityExtensions
{
public static bool IsInIdentityRole(this IPrincipal user, string role)
{
var userManager = GetUserManager(); //implement this!
return userManager.IsInRole(user.Identity.GetUserId(), role);
}
}
}
确保您的观点了解此命名空间,将此行添加到Views文件夹中的web.config
文件中(不是主web.config
!):
<add namespace="MyProject.MyNamespace.MyExtensions"/>
并在您的视图中使用:
@if (User.IsInIdentityRole("admin"))
{
<li>@Html.ActionLink("Admins", "Index", "Admins")</li>
}
答案 1 :(得分:0)
而不是打电话
@if (Roles.IsUserInRole(User.Identity.Name,"admin"))
调用旧的MembershipProvider使用此调用:
@if (User.IsInRole("admin"))
这使用了新Identity框架的功能。无需实施任何东西。此外,这不会调用数据库来检查角色 - 它使用存储用户角色的cookie信息。
<强>更新强>
如果您对System.Web.Security.RolePrincipal
有例外,这意味着您的会员资格提供商没有完全关闭,而且您认为这是最后一次机会。
确保您拥有web.config
:
<system.WebServer>
<modules>
<remove name="FormsAuthentication" />
并在
<appSettings>
<add key="enableSimpleMembership" value="false" />
确保您的Cookie已删除,您可以再次登录。之后,当您在调试器中检查Razor视图中的@User
时,您应该看到ClaimsPrincipal
对象,而不是RolePrincipal
。当用户登录时,应在整个系统中使用ClaimsPrincipal
- 这是Identity使用的内容。如果您没有IdentityPrincipal
,则表示您的登录过程无法正常运行。