Reputation: 18464
I have a .NET 4.5 claims-aware application hosted in Windows Azure. There is a web role that hosts the MVC site and a worker role that runs jobs in the background. Users can choose to remain permanently logged in.
Here is code from my ClaimsAuthenticationManager:
public ClaimsPrincipal LogIn(string username, bool rememberMe = false)
{
ClaimsPrincipal principal = Authenticate(null, principalFactory.CreateFormsPrincipal(username));
SetSessionCookie(principal, rememberMe ? TimeSpan.MaxValue : TimeSpan.FromDays(1));
return principal;
}
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (!incomingPrincipal.Identity.IsAuthenticated)
{
return base.Authenticate(resourceName, incomingPrincipal);
}
return principalFactory.Create(incomingPrincipal.Identity.Name, incomingPrincipal.Identity.AuthenticationType);
}
private static void SetSessionCookie(ClaimsPrincipal principal, TimeSpan lifetime)
{
var sessionSecurityToken = new SessionSecurityToken(principal, lifetime)
{
IsReferenceMode = true
};
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken);
}
In the simple refresh case where the user performs an action (e.g., purchases/cancels a subscription) on the site, this can be done by:
What I need some guidance on is how/when to refresh a user's claims when they change as a result of a non-user-originated event.
Imagine the following scenarios:
A user specifices "remember me" and logs in successfully. He now has a cookie that never expires. He then purchases a subscription via the site. His claims are refreshed via option #1 above. One month later, his subscription lapses because he chose not to renew. But his cookie is still valid and the claims associated with it say that his subscription is still active.
A new user creates an account and logs in successfully specifying "remember me". He now has a cookie that never expires which includes a claim granting a free one week trial of some special functionality. One week later, a background job (executing via the worker role) removes the record of the free trial in the underlying data store. However, the user's cookie still has the free trial claim.
In both scenarios, if the user logged out and back in on his own, the problem would solve itself. But, if the user takes no specific action to log out, his cookie contains invalid claims.
How do you handle cases like these?
As I've been composing this question, it occurred to me that the most logical thing to do is to set the cookie's expiration date to the intended lifetime of the shortest-lived claim in the claims collection.
Is there a better or different strategy?
Any guidance would be greatly appreciated.
Thanks.
For reference, I have read the following posts on related topics:
Upvotes: 2
Views: 427
Reputation: 48279
I know this is a bit old, however I believe a short answer to both concerns is just to include a custom claim together with the session token in a cookie. This custom claim value would be the subscription id.
Upon any sensitive request, the subscription id would be checked against the list of valid subscriptions.
In other words rather than
the most logical thing to do is to set the cookie's expiration date to the intended lifetime of the shortest-lived claim in the claims collection
it should be "don't rely solely on the session token from the cookie, rather verify permissions as often as necessary, possibly with some additional claims that make this verification cheaper".
Upvotes: 1