成功登录后,User.Identity.IsAuthenticated为false。

34

我需要在成功登录后直接获取用户Id Guid。以下代码无法正常工作:

if (Membership.ValidateUser(txtUsername.Value, txtPassword.Value))
{
    FormsAuthentication.SignOut();
    FormsAuthentication.SetAuthCookie(txtUsername.Value, true);

    if (HttpContext.Current.User.Identity.IsAuthenticated)
    {
        // doesn't run
        Guid puk = (Guid)Membership.GetUser().ProviderUserKey;            
    }
}

以下代码是可行的:
if (Membership.ValidateUser(txtUsername.Value, txtPassword.Value))
{
    FormsAuthentication.SignOut();
    FormsAuthentication.SetAuthCookie(txtUsername.Value, true);

    MembershipUser user = Membership.GetUser(txtUsername.Value);

    if (user != null)
    {
        Guid puk = (Guid)user.ProviderUserKey;
    }
}

为什么会发生这种情况?除了SetAuthCookie,还有其他需要做的事情吗?
5个回答

24

我也遇到了同样的问题。我忘记设置 web.config 配置。

也许你也是这个问题。

   <system.web> 
    <authentication mode="Forms">
      <forms loginUrl="~/user/login" timeout="1000" name="__Auth" />
    </authentication>  
  </system.web> 

19
因为当你调用FormsAuthentication.SetAuthCookie(txtUsername.Value, true);时,你会将密钥存储在客户端的cookies中。为此,您需要向用户发送响应。 而要使用HttpContext.Current.User.Identity填充cookie,您需要再进行一次请求。
简而言之,您的方案如下:
  1. 客户端发送他的用户名和密码。

  2. 服务器获取并检查它。如果它们有效,则服务器将Set-Cookie头发送给客户端。

  3. 客户端接收并存储它。对于每个请求,客户端都会将cookies发送回服务器。

更新@Jake 添加在HttpContext中设置User的示例。
var identity = new System.Security.Principal.GenericIdentity(user.UserName);
var principal = new GenericPrincipal(identity, new string[0]);
HttpContext.Current.User = principal;
Thread.CurrentPrincipal = principal;  

请注意,您可以创建继承自GenericPrincipalClaimsPrincipal的自定义主体类。


有没有办法在同一请求中访问用户身份标识? - Ahmad Ahmadi
1
@AhmadAhmadi,你可以手动将CustomPrincipal对象分配给HttpContext的User属性来进行设置。 - Oleksii Aza
1
@OleksiiAza,你能否更新你的答案,展示如何做到这一点? - Jake

4
在我的开发环境中,requireSSL属性被设置为true,我通过将其更改为requireSSL = false来解决了问题。

enter image description here


3

我尝试了所有以上的解决方案,但是解决我的问题的方法是在web.config文件中注释掉这个内容。

 <modules>
  <remove name="FormsAuthentication"/>
 </modules>

这将完全移除表单身份验证,因此当然会让用户通过。 - Synctrex
这并没有移除表单身份验证,但我不确定它在做什么。现在,已经移除了该模块,true/false 工作正常;...奇怪? - Zonus

0
我在一个 Blazor .NET 6 WASM 应用程序中遇到了这个错误。我按照下面的指南将身份验证状态公开为级联参数:

https://learn.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-6.0#expose-the-authentication-state-as-a-cascading-parameter

这个方法很有效,但是当与OnInitializedAsync一起使用时,即使成功登录后user.Identity.IsAuthenticated也会被设置为false,但在刷新页面后可以正常工作。

将组件生命周期更改为OnParametersSetAsync可以解决这个问题。

https://learn.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-6.0#after-parameters-are-set-onparameterssetasync

MainLayout.razor中完成代码:

@code {
    bool loadData = true;

    [CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }

    protected override async Task OnParametersSetAsync()
    {
        var authState = await authenticationStateTask;
        var user = authState.User;

        if (user.Identity.IsAuthenticated)
        {
            loadData = true;

            await StateContainer.LoadDataAsync();

            loadData = false;
        }
        else
        {
            loadData = false;
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接