'Claims lost after a period of inactivity
I am integrating the asp.net webforms project with single sign on(SSO) using Openidconnect and Cookie Authentication using Owin libraries. Once authenticated, the cookie should be active for the day and on browser close need to reauthenticate again(which sets up the cookie again).
After certain hours of inactivity it shows user is authenticated, but the ClaimsIdentity is lost. So the app does not work. I need to able to get the name/email address from the Claims.
How can I fix this?
Startup.cs
public void ConfigureAuth(IAppBuilder app)
{
try
{
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.SetDefaultSignInAsAuthenticationType("Identity.Application");
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Identity.Application",
ExpireTimeSpan = 1440,//min
CookieName = "ABC",
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = _clientId,
Authority = _authority,
RedirectUri = _redirectUri,
ResponseType = "code",
Scope = "openid",
SignInAsAuthenticationType = "Identity.Application",
RedeemCode = true,
SaveTokens = true,
ClientSecret = _clientSecret,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
AuthenticationFailed = (context) =>
{
return Task.FromResult(0);
},
AuthorizationCodeReceived = (context) =>
{
Console.WriteLine("ConfigureAuth: AuthorizationCodeReceived");
return Task.FromResult(0);
},
MessageReceived = (context) =>
{
Console.WriteLine("ConfigureAuth: MessageReceived");
return Task.FromResult(0);
},
RedirectToIdentityProvider = (context) =>
{
Console.WriteLine("ConfigureAuth: RedirectToIdentityProvider");
return Task.FromResult(0);
},
SecurityTokenReceived = (context) =>
{
Console.WriteLine("ConfigureAuth: SecurityTokenReceived");
return Task.FromResult(0);
},
SecurityTokenValidated = (context) =>
{
Console.WriteLine("ConfigureAuth: SecurityTokenValidated");
return Task.FromResult(0);
}
}
});
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.ToString());
}
}
Web.config
<authentication mode="Forms">
<forms loginUrl="AuthenticationHandler.ashx" name=".ASPNETAUTH" protection="None" path="/Default3.aspx" timeout="420" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
<sessionState timeout="420" />
AuthenticationHandler
public class AuthenticationHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (!context.Request.IsSecureConnection)
{
string absoluteUri = context.Request.Url.AbsoluteUri;
context.Response.Redirect(absoluteUri.Replace("http://", "https://"), true);
}
if (context.Request.IsAuthenticated)
{
string userName = String.Empty;
var claimsIdentity = context.User.Identity as ClaimsIdentity;
foreach (var claim in claimsIdentity.Claims)
{
if (claim.Type == "name")
{
userName = claim.Value;
break;
}
}
// Redirect back to original URL.
string redirectUrl = FormsAuthentication.GetRedirectUrl(userName, true);
if (!redirectUrl.Contains("default.aspx"))
{
context.Response.Redirect(redirectUrl);
}
}
else
{
ChallengeAuthentication(context);
}
if (!String.IsNullOrEmpty(context.Request.QueryString["signout"]))
{
context.Request.GetOwinContext()
.Authentication
.SignOut(HttpContext.Current.Request.GetOwinContext()
.Authentication.GetAuthenticationTypes()
.Select(o => o.AuthenticationType).ToArray());
}
}
private static void ChallengeAuthentication(HttpContext context)
{
try
{
HttpContext.Current.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties { RedirectUri = context.Request.RawUrl },
OpenIdConnectAuthenticationDefaults.AuthenticationType);
var claimsIdentity = context.User.Identity as ClaimsIdentity;
string userName = string.Empty;
foreach (var claim in claimsIdentity.Claims)
{
string claimType = claim.Type.Replace("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/", "");
string claimValue = claim.Value;
sbMessage.Append(claimType + " = " + claimValue + "<br/>");
if (claimType == "emailaddress")
{
userName = claimValue;
}
}
context.Response.Write(sbMessage.ToString());
string userData = "";
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
userName,
DateTime.Now,
1440,
true,
userData,
FormsAuthentication.FormsCookiePath);
// Encrypt the ticket.
string encTicket = FormsAuthentication.Encrypt(ticket);
// Create the cookie.
context.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
}
catch (Exception ex)
{
Console.WriteLine("exception authenticating: " + ex.ToString());
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
Default3.aspx.cs
string userName = String.Empty;
var claimsIdentity = User.Identity as ClaimsIdentity;
foreach (var claim in claimsIdentity.Claims)
{
// WEC:: might need a more bulletproof check here.
string claimType = claim.Type.Replace("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/", "");
string claimValue = claim.Value;
if (claimType == "emailaddress")
{
userName = claimValue;//NO VALUE after certain hours of inactivity
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
