Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.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# 将网站重新部署到IIS会导致已登录的用户无法再次登录?_C#_Asp.net Mvc_Azure_Iis_Cookies - Fatal编程技术网

C# 将网站重新部署到IIS会导致已登录的用户无法再次登录?

C# 将网站重新部署到IIS会导致已登录的用户无法再次登录?,c#,asp.net-mvc,azure,iis,cookies,C#,Asp.net Mvc,Azure,Iis,Cookies,问题 我有一个ASP.NET站点,当我最初部署该站点时,它在登录/注销方面工作得非常好。当我重新部署新更改(通过替换文件)时,那些已登录(具有cookie)的人将不再被识别为已登录。此外,他们无法登录,因为单击“登录”会使他们进入azure登录,然后它会重定向回主页,并且不会检测到cookie,因此显示他们仍然注销 只有当我部署到QA(IIS 6.2)时,VisualStudio和IIS Express中才会发生这些事情 相关代码 会计控制员 AzureSettings从Startup.cs运行

问题

我有一个ASP.NET站点,当我最初部署该站点时,它在登录/注销方面工作得非常好。当我重新部署新更改(通过替换文件)时,那些已登录(具有cookie)的人将不再被识别为已登录。此外,他们无法登录,因为单击“登录”会使他们进入azure登录,然后它会重定向回主页,并且不会检测到cookie,因此显示他们仍然注销

只有当我部署到QA(IIS 6.2)时,VisualStudio和IIS Express中才会发生这些事情

相关代码

会计控制员

AzureSettings从Startup.cs运行

上面代码中引用的PrincipalService.cs

//
///将用户重定向到/Home/ErrorInfo页面。
/// 
OnAzureAuthenticationFailure的公共静态任务(AuthenticationFailedNotification上下文)
{
context.HandleResponse();
context.Response.Redirect(“/Home/ErrorInfo”);
返回Task.FromResult(0);
}
/// 
///存储正确的标识cookie(尚未具有客户权限)。
/// 
OnAzureAuthenticationSuccess上的公共静态任务(AuthorizationCodeReceivedNotification上下文)
{
var username=context.AuthenticationTicket.Identity.Name;
尝试
{
StoreCookie(用户名);
}
捕获(DbEntityValidationException ex)
{
var errors=ex.EntityValidationErrors.FirstOrDefault()?.ValidationErrors.FirstOrDefault()?.ErrorMessage;
Logger.Log(Level.Error,“存储身份验证cookie时发生错误”,例如);
}
捕获(例外情况除外)
{
Logger.Log(Level.Error,“存储身份验证cookie时发生错误”,例如);
}
返回Task.FromResult(0);
}
/// 
///为用户创建并存储表单身份验证cookie。
/// 
私有静态void StoreCookie(字符串用户名,bool rememberMe=false)
{
Logger.Log(Level.Info,“存储Cookie”);
var azureUsers=new AzureUserRepository(new AuthenticationEntities());
var user=azureUsers.Get(u=>u.Username==Username);
if(user==null)
{
抛出新的NullReferenceException();
}
//清除所有旧的现有cookie。
HttpContext.Current.Request.RemoveFormsAuthCookie();
//从用户对象创建主体。
var principal=新PrincipalModel(用户);
//在响应中创建并存储cookie。
var serializer=新的JavaScriptSerializer();
serializer.RegisterConverters(新的JavaScriptConverter[]{
新建ActivityConverter(),
新RoleConverter(),
新PrincipalModelConverter()
});
HttpContext.Current.Response.AddFormsAuthCookie(
用户名:user.username,
userData:serializer.Serialize(主体),
持久的:记住
);
}
摘要

  • 将站点重新部署到QA会导致仍然登录的用户不再被服务器识别为已登录(因此显示登录链接)
  • 之后,单击“登录”将他们带到azure登录,然后将他们重定向到主页,在那里他们无法识别为已登录
  • 在Chrome中删除页面的Cookie将修复此问题,直到下次发生
  • 只有当我部署到QA的IIS6.2时(我们还没有生产服务器),在开发(Visual Studio和IIS Express)时才会发生这种情况

我是怎么做的?需要做些什么来防止这种情况发生?

据我所知,避免这种情况的唯一方法是使用会话

您可以使用sql server或Redis缓存来持久化会话状态

更多信息:


我相信这个问题已经解决了。不确定我是否100%理解了原因,但在上面的代码中,我在添加之前从请求而不是响应中删除了旧cookie。一旦我添加了从响应中删除cookie的代码,它就停止导致问题

(注:如果有人能解释这是为什么,我很乐意接受他们的回答)

[AllowAnonymous]
public void SignIn()
{
    if (Request.IsAuthenticated) { return; }

    HttpContext.GetOwinContext().Authentication.Challenge(
        new AuthenticationProperties() { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType
    );
}

public void SignOut()
{
    if (!Request.IsAuthenticated) { return; }

    // SIGN OUT:
    HttpContext.GetOwinContext().Authentication.SignOut(
        OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType
    );

    // COOKIE: Remove the cookie.
    var cookie = Request.Cookies[FormsAuthentication.FormsCookieName];
    cookie.Expires = DateTime.UtcNow.AddDays(-1);
    Response.Cookies.Add(cookie);
}
public static void ConfigureAzure(IAppBuilder app)
{
    // COOKIES: Tells it to use cookies for authentication.
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    app.UseCookieAuthentication(new CookieAuthenticationOptions()
    {
        // CUSTOMIZE: This is where you would adjust cookie experiation and things of that nature.
    });

    //https://azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-webapp-webapi-openidconnect/
    // OPEN-ID: Handle OpenID stuff.
    var notifications = new OpenIdConnectAuthenticationNotifications()
    {
        AuthenticationFailed = PrincipalService.OnAzureAuthenticationFailure,
        // REFERENCE: https://russellyoung.net/2015/09/05/mvc-role-based-authorization-with-azure-active-directory-aad/
        AuthorizationCodeReceived = PrincipalService.OnAzureAuthenticationSuccess
    };
    var options = new OpenIdConnectAuthenticationOptions()
    {
        ClientId = ClientID,
        Authority = Authority,
        PostLogoutRedirectUri = PostLogoutRedirectUri,
        Notifications = notifications
    };
    app.UseOpenIdConnectAuthentication(options);
}
/// <summary>
/// Redirects the user to the /Home/ErrorInfo page.
/// </summary>
public static Task OnAzureAuthenticationFailure(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
{
    context.HandleResponse();
    context.Response.Redirect("/Home/ErrorInfo");
    return Task.FromResult(0);
}

/// <summary>
/// Stores the proper identity cookie (doesn't have customer permissions yet).
/// </summary>
public static Task OnAzureAuthenticationSuccess(AuthorizationCodeReceivedNotification context)
{
    var username = context.AuthenticationTicket.Identity.Name;
    try
    {
        StoreCookie(username);
    }
    catch (DbEntityValidationException ex)
    {
        var errors = ex.EntityValidationErrors.FirstOrDefault()?.ValidationErrors.FirstOrDefault()?.ErrorMessage;
        Logger.Log(Level.Error, "An error occurred while storing authentication cookie.", ex);
    }
    catch (Exception ex)
    {
        Logger.Log(Level.Error, "An error occurred while storing authentication cookie.", ex);
    }
    return Task.FromResult(0);
}

/// <summary>
/// Creates and stores a forms authentication cookie for the user.
/// </summary>
private static void StoreCookie(string username, bool rememberMe = false)
{
    Logger.Log(Level.Info, "Storing Cookie");
    var azureUsers = new AzureUserRepository(new AuthenticationEntities());
    var user = azureUsers.Get(u => u.Username == username);
    if (user == null)
    {
        throw new NullReferenceException();
    }

    // Clear any old existing cookies.
    HttpContext.Current.Request.RemoveFormsAuthCookie();

    // Create the principal from the user object.
    var principal = new PrincipalModel(user);

    // Create and store the cookie in the response.
    var serializer = new JavaScriptSerializer();
        serializer.RegisterConverters(new JavaScriptConverter[] {
        new ActivityConverter(),
        new RoleConverter(),
        new PrincipalModelConverter()
    });
    HttpContext.Current.Response.AddFormsAuthCookie(
        username: user.Username,
        userData: serializer.Serialize(principal),
        isPersistent: rememberMe
    );
}