Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET MVC4身份验证成功,但在项目生成后缺少角色_C#_Asp.net_Asp.net Mvc_Asp.net Mvc 4_Simplemembership - Fatal编程技术网

C# ASP.NET MVC4身份验证成功,但在项目生成后缺少角色

C# ASP.NET MVC4身份验证成功,但在项目生成后缺少角色,c#,asp.net,asp.net-mvc,asp.net-mvc-4,simplemembership,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 4,Simplemembership,我已经搜索了很多SO和其他页面,但仍然找不到类似的案例 我的应用程序使用SimpleMembership。它具有基于角色的用户菜单,大多数操作都具有[Authorize(Roles=“aaa,bbb”)]属性 在应用程序构建完成或浏览器闲置一段时间后,用户将从单击的任何链接重定向到登录页面。奇怪的是,登录名仍然可以显示,但它没有附加角色名 在上述情况下,用户可以使用[Authorize]属性访问操作。我想知道我是否遗漏了什么,或者只要身份验证有效,我就可以保持角色信息的活动状态 以下是控制器操作

我已经搜索了很多SO和其他页面,但仍然找不到类似的案例

我的应用程序使用SimpleMembership。它具有基于角色的用户菜单,大多数操作都具有[Authorize(Roles=“aaa,bbb”)]属性

在应用程序构建完成或浏览器闲置一段时间后,用户将从单击的任何链接重定向到登录页面。奇怪的是,登录名仍然可以显示,但它没有附加角色名

在上述情况下,用户可以使用[Authorize]属性访问操作。我想知道我是否遗漏了什么,或者只要身份验证有效,我就可以保持角色信息的活动状态

以下是控制器操作中用于呈现菜单的代码:

自定义_logonPartial以显示登录名和角色

> @if (Request.IsAuthenticated) {
    <text>
        Logged in: @Html.ActionLink(User.Identity.Name, "Manage", "Account", routeValues: null, htmlAttributes: new { @class = "username", title = "Manage" }) as
        @String.Join(",", Roles.GetRolesForUser(User.Identity.Name))
        @using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" })) {
            @Html.AntiForgeryToken()
            <a href="javascript:document.getElementById('logoutForm').submit()">Log off</a>
        }
    </text>
@if(Request.IsAuthenticated){
登录:@Html.ActionLink(User.Identity.Name,“Manage”,“Account”,routeValue:null,htmlAttributes:new{@class=“username”,title=“Manage”})作为
@String.Join(“,”,Roles.GetRolesForUser(User.Identity.Name))
@使用(Html.BeginForm(“注销”、“帐户”、FormMethod.Post、新{id=“logoutForm”})){
@Html.AntiForgeryToken()
}

只要用户登录,角色信息就可用。在您的情况下,您正在呼叫:

Roles.GetRolesForUser(User.Identity.Name)
获取角色列表。这实际上会访问数据库以获取角色,因此只要用户名在标识中可用,它将返回角色,假设用户已分配给角色。如果用户id已验证,则用户名应可用。您正在检查Request.IsAuthenticated。检查U可能更好ser.Identity.I已验证

有一种方法可以在不使用声明查询数据库的情况下获取角色。一般来说,我不会在您的视图中放置此类逻辑和对系统变量的访问。我会在控制器操作中使用这种方法来获取角色

        var prinicpal = (ClaimsPrincipal)Thread.CurrentPrincipal;
        var roles = prinicpal.Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value);
        ViewBag.Roles = roles;
将所需信息放入视图包中的视图中,或创建传递给视图的模型。这种获取角色的方法不需要往返数据库

更新以处理评论

MVC 4的标准authorized属性使用配置的成员资格和角色提供程序(在您的示例中为SimpleMembership)获取角色。它不假设声明在何处使用,因此每次都会进入数据库。事实上,它必须进入数据库两次,一次获取登录用户的用户ID,然后根据该用户ID获取角色。效率不高。令人惊讶的是,即使您没有将任何角色作为参数传递,它也会这样做,而在没有传递参数的情况下需要根据角色对用户进行授权,并且应该只进行身份验证。我使用探查器对此进行了验证

为了提高效率,并且不需要访问数据库,您可以编写一个自定义的AuthorizeAttribute来使用声明,并带有指向示例源代码的链接


我无法解释您正在描述的场景,它发生在构建之后。但是,如果您创建一个自定义属性并使用它,您将能够调试并查看到底发生了什么。另外,我不会太担心它,因为它不应该是您在生产中看到的典型场景。

谢谢您的回答。这种情况问题是:每次生成后,当用户访问
[Authorize(Roles=“XXX,BBB”)]
操作时,将重定向到登录页面。这不会发生在
[Authorize]
操作中(用户可以在生成后访问).根据我的观察,用户在生成后仍然登录,但缺少角色。这是一个数据库连接超时问题吗?我想知道在执行action属性时是否有任何可能的方法保留角色。ThanksI尝试构建应用程序,旨在模拟丢失角色的空闲情况。现已解决“角色丢失但经过身份验证”是IIS应用程序池的空闲超时。延长了超时时间,工作正常。感谢您的帮助。
        var prinicpal = (ClaimsPrincipal)Thread.CurrentPrincipal;
        var roles = prinicpal.Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value);
        ViewBag.Roles = roles;