【问题标题】:MVC Not holding on to authenticationMVC 不坚持身份验证
【发布时间】:2017-04-07 15:22:44
【问题描述】:

我正在开发两个应用程序。它们都需要同时使用 Windows 身份验证和匿名访问。所以为了做到这一点,我编辑了 web.config 以摆脱授权标签(使用“拒绝用户 =”?“”)并且只用我的自定义授权属性标记了一些操作。麻烦的是,服务器正在“忘记”我。因此,例如,在第一个应用程序上,一个用户报告说她必须每隔一次她想要编辑时尝试访问控制面板。在第二个中,我单击登录,我已登录,然后单击任何其他链接(尤其是“保存”)并退出。

这是我的自定义授权属性之一:

public class AccountsAuthorizeITAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if(httpContext.User.Identity.IsAuthenticated == false)
        {
            return false;
        }

        if(httpContext.User.IsInRole("CT-IT"))
        {
            return true;
        }

        return false;
    }
}

要登录,我的 _layout 中有这个:

@Html.ActionLink("Login", "Login", "Login", new { returnURL = HttpContext.Current.Request.RawUrl }, null)

使用此登录控制器:

public class LoginController : Controller
{
    [AccountsAuthorizeIT]
    public ActionResult Login(string returnURL)
    {
        return Redirect(returnURL);
    }
}

是什么原因造成的?我的身份验证不应该存储在会话变量中,只要浏览器窗口打开就保存(大约)?我需要告诉服务器记住我的数据吗?

【问题讨论】:

  • 您使用什么进行身份验证?表格、会员资格、身份?
  • web.config 中的授权标签用于 ASP.NET Web 窗体。您不应该在 ASP.NET MVC 中使用。您是否使用 Active Directory 进行身份验证?请出示您的登录代码。
  • @SalvadorGuerrero 没有。什么是机器钥匙?
  • 身份验证存储在会话变量中。 Session 永远不应该用于身份验证。这是不安全和不可靠的,因为会话可能随时丢失(IIS 不保证它们会保持活动状态)。身份验证由一个特殊的身份验证 cookie 处理,它可以是临时的(不存储在磁盘上)或持久的(存储在磁盘上)。
  • 我也不明白您为什么需要自定义授权属性。您所要做的就是使用标准的[Authorize(Role="CT-IT")],它的作用与您的自定义属性完全一样。

标签: c# asp.net-mvc authentication


【解决方案1】:

我的身份验证不应该存储在会话变量中吗? (大约)只要浏览器窗口打开?我需要告诉 服务器来记住我的数据?

我个人喜欢使用 OWIN Cookie 中间件将它们作为声明存储在 Principle 对象中。

Here 是示例代码。 roleNames 可以是用户分配的 Active Directory 组。

public void SignIn(User user, IList<string> roleNames)
{
    IList<Claim> claims = new List<Claim>
            {
                new Claim(ClaimTypes.Sid, user.Id.ToString()),
                new Claim(ClaimTypes.Name, user.UserName),
                new Claim(ClaimTypes.GivenName, user.FirstName),
                new Claim(ClaimTypes.Surname, user.LastName),
            };

    foreach (string roleName in roleNames)
    {
        claims.Add(new Claim(ClaimTypes.Role, roleName));
    }

    ClaimsIdentity identity = new ClaimsIdentity(claims, AuthenticationType);

    IOwinContext context = _context.Request.GetOwinContext();
    IAuthenticationManager authenticationManager = context.Authentication;

    authenticationManager.SignIn(identity);
}

Startup.cs

然后在启动时注册 OWIN Cookie 中间件。

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "ApplicationCookie",
            LoginPath = new PathString("/Account/Login")
        });
    }
}

如果您将它们存储在 Principle 对象中,您甚至不需要自定义属性 AccountsAuthorizeITAttribute

【讨论】:

  • 我尝试将其调整为我的代码(使用 stackoverflow.com/questions/5309988/… 查找活动目录组,忽略 ClaimTypes.Sid​​ 和用户未提供的其他声明类型,使用“Windows”而不是“AuthenticationType " 在 ClaimsIdentity 中),但我在任何东西上都找不到 GetOwinContext。它是我需要安装的软件包吗?
  • 你可以查看所有需要的包here
  • 太好了,我能够安装一些 owin 软件包并编译所有内容。但是,有两个问题:1)每当我启动应用程序时,无论我尝试启动哪个页面,它都会将自己重定向到登录页面,以及 2)由于某种原因,它重定向到的登录页面会多次重定向到自身我收到错误消息:“请求过滤模块配置为拒绝查询字符串过长的请求。”我尝试在登录代码中放置一个断点,但没有成功。我想我注定要制作一个公共版本和一个 windows auth 版本。
  • 你需要在Login HttpGet方法和HttpPost方法上放置[AllowAnonymous]属性。
  • 所以这样做意味着我失去了将某些区域设为公共区域和将某些区域设为私有区域的能力?
猜你喜欢
  • 2021-08-04
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 2012-08-21
  • 2017-10-06
  • 2015-07-18
  • 2023-03-22
  • 2018-04-18
相关资源
最近更新 更多