不使用 FormsAuthentication.RedirectFromLoginPage 时如何将 Request.IsAuthenticated 设置为 true?

Posted

技术标签:

【中文标题】不使用 FormsAuthentication.RedirectFromLoginPage 时如何将 Request.IsAuthenticated 设置为 true?【英文标题】:How to set Request.IsAuthenticated to true when not using FormsAuthentication.RedirectFromLoginPage? 【发布时间】:2011-01-07 12:05:02 【问题描述】:

我正在使用表单身份验证并向服务器发送 Aajx 请求以进行身份​​验证。根据 json 结果,客户端决定去哪里以及做什么。这就是我不使用 FormsAuthentication.RedirectFromLoginPage 来不干扰 ajax/json 响应的原因。

在这种情况下,Request.IsAuthenticated 返回 false,即使在使用 Membership.ValidateUser 验证用户之后也是如此。然后我使用

设置 cookie
FormsAuthentication.SetAuthCookie(username, false);

虽然第二个参数persistent cookie 为false,但cookie 在浏览器会话中仍然有效。

知道如何在不使用 FormsAuthentication.RedirectFromLoginPage 的情况下使 Request.IsAuthenticated 工作吗?

【问题讨论】:

您可能没有使用 AJAX 请求正确设置 cookie... 您是否尝试按照msdn.microsoft.com/en-us/library/bb398896.aspx 的msdn 说明进行操作? 如果您试图在您的 ajax 身份验证请求(即 SPA)中生成并返回一个防伪令牌,这尤其成问题。 Asp.Net 将为 "" 用户生成令牌,因为它假定当前没有人经过身份验证。 【参考方案1】:

我们可以简单地使用它

FormsAuthentication.SetAuthCookie(username, true);

【讨论】:

【参考方案2】:

在 POST 之后重定向是最佳做法,应该被视为正确的解决方案。

在某些情况下,您可能仍想了解用户是否在身份验证请求的范围内进行了身份验证(例如,如果您在执行身份验证后运行与其他请求共享的附加逻辑)。

在这种情况下,您可以使用以下代码重置 Request.IsAuthenticated 的值:

// set the forms auth cookie
FormsAuthentication.SetAuthCookie(username, createPersistentCookie);

// reset request.isauthenticated
var authCookie = System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)

    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    if (authTicket != null && !authTicket.Expired)
    
        var roles = authTicket.UserData.Split(',');
        System.Web.HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(authTicket), roles);
    
 

在此处查看帖子:http://abadjimarinov.net/blog/2010/01/24/RenewUserInTheSameRequestInAspdotNET.xhtml

【讨论】:

【参考方案3】:

FormsAuthentication.SetAuthCookie

方法 创建身份验证 提供的用户名的票证和 将其添加到 cookie 集合中 响应,或者如果你是 URL 使用无 cookie 身份验证。

参考:msdn

看看Forms Authentication Control Flow。身份验证 cookie 设置为响应 cookie 集合,并且应该在 http 协议级别是可观察的(例如,使用 FireCookie 或 Fiddler2 来验证这一点)。

会员资格仅验证用户名/密码。 Membership 和SetAuthCookie() 都不会修改当前请求。他们希望将 cookie 发送回调用者,而 下一个 请求是 IsAuthenticated 之类的属性将返回 true 的时间。

请注意,您可以使用自定义 IIdentityIPrincipal 覆盖和扩展这些自动流程,并在需要时挂钩身份验证事件。

也可以看看Using Forms Authentication with ASP.NET AJAX

【讨论】:

我使用 Fiddler 查看请求和响应中的 cookie【参考方案4】:

您需要更新请求的当前安全主体。当您调用 Response. Redirect(...) 时,完成了一个新请求并且重新初始化了安全主体,并且 Request.IsAuthenticated 在您的情况下返回 true。 FormsAuthentication.RedirectFromLoginPage 内部调用 Response. Redirect(...)。您可以像这样手动更新当前请求的安全主体:

public void RenewCurrentUser()

    System.Web.HttpCookie authCookie =
        System.Web.HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null)
    
        FormsAuthenticationTicket authTicket = null;
        authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        if (authTicket != null && !authTicket.Expired)
        
            FormsAuthenticationTicket newAuthTicket = authTicket;

            if (FormsAuthentication.SlidingExpiration)
            
                newAuthTicket = FormsAuthentication.RenewTicketIfOld(authTicket);
            
            string userData = newAuthTicket.UserData;
            string[] roles = userData.Split(',');

            System.Web.HttpContext.Current.User =
                new System.Security.Principal.GenericPrincipal(new FormsIdentity(newAuthTicket), roles);
        
    

【讨论】:

不需要手动续订(尤其是对于 GenericPrincipal 和 FormsIdentity),并且凭据不应在请求的中途更改,这就是为什么将 cookie 添加到响应中,然后是全新的响应/request 生命周期被执行。在下一个请求中,由 FormsAuthentication.SetAuthCookie() 创建的 cookie 将被拾取。 当然这种方法可以被认为是一种 hack,因为它不遵循正常的表单身份验证流程。但是,如果您想检查用户是否在参与身份验证的同一请求中进行了身份验证,这可能会很有用。 有时虽然黑客是你需要的——我试图以“正确的方式”做事并强制重定向,并在其他系统被重定向的情况下进入正确的状态:( 谢谢 +Branislav Abadjimarinov 这非常有帮助 我使用此代码编写了一个名为 AjaxRenewPrincipal() 的控制器扩展,它非常适用于对同一请求进行身份验证!谢谢!

以上是关于不使用 FormsAuthentication.RedirectFromLoginPage 时如何将 Request.IsAuthenticated 设置为 true?的主要内容,如果未能解决你的问题,请参考以下文章

c语言报错不允许使用不完整类型,让用户自定义数组大小。

参数标志,不使用时为空,不使用时为默认值

如何设置相机视图旋转(不使用不推荐使用的代码)

使用 jQuery 提交表单并使用 PHP 发送.. 不知道为啥它不发送

UITableViewCell 不使用不推荐使用的方法 initWithFrame:reuseIdentifier

不推荐使用:不推荐使用 FCM 直接通道,请使用 APNs 进行下游消息处理