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