Updating Claims Value without logging out and back in - asp.net-mvc

I set Claim value after register user.
await _userManager.AddClaimAsync(user.Id,new Claim("DeActive", "1"));
user only visit special pages. after fill a form i remove this Claim, The user can now access all pages.
await _userManager.RemoveClaimAsync(CurrentUser.UserId, new Claim("DeActive", "1"));
But the problem is that the user has to log in again to clear the Claim.
How to update Claims value without logout?

Yes, your claim will update, after you remove/add it.
The issue is HOW LONG does it take... in your startupAuth.cs you have setting that needs to be modified my guess is you used the default its ~30 mins, change that to
TimeSpan.FromMinutes(30) to TimeSpan.FromMilliseconds(75)
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/HiddenLogin"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30), // change this as above
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});

Related

Mixing ASP.net Identity and Azure AD authentication

We use ASP.Net Identity for our DB backed login currently and need to add support for Azure AD SSO.
I appreciate once logged in I will need to link the SSO user to a user in our system to assign the relevant Claims and Roles but am struggling to get the 2 authentication methods working side by side and app.UseCookieAuthentication seems to be at the root of my problems.
Currently we have:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Login/Index"),
ReturnUrlParameter = "url",
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, IdentityUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
},
ExpireTimeSpan = TimeSpan.FromMinutes(double.Parse(ConfigurationManager.AppSettings["AuthenticationTimeout"])),
SlidingExpiration = true
});
With this in I suspect the cookie returned by the SSO isn't getting processed correctly as the Request.IsAuthenticated is always false.
If I change it to:
app.UseCookieAuthentication(new CookieAuthenticationOptions());
Then the SSO works and returns me an authenticated request but obviously breaks the Identity login.
For info my OpenId setup is as follows, for now just trying to get it to work with our work AD but eventually will need to expand to multi tenant:
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
RedirectUri = redirectUri,
PostLogoutRedirectUri = redirectUri,
Scope = OpenIdConnectScope.OpenIdProfile,
ResponseType = OpenIdConnectResponseType.IdToken,
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = false
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed
}
}
);
Any help or pointers appreciated.
try using the
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
before
app.UseOpenIdConnectAuthentication

Asp.net identity keep user login

I have to keep user login for 15 hours but its logout after about 20 minutes of inactivity.
My code in startup.auth.cs is
public void ConfigureAuth(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
ExpireTimeSpan = TimeSpan.FromHours(15),
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
SlidingExpiration = true,
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(0),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
}
}
Why user is logged out after about 20 minutes of inactivity?
As you say, you want to keep session active then put this following key in web.config.
maybe your application session get expired in 20 minutes(it is default value )
<sessionState timeout="900" cookieless="AutoDetect">

Is it possible to change HttpContext.Current.User.Identity.Name after change username

I'm working on a ASP MVC application. And want to change username without making user logout. I am using Identity Provider version 1.0.11. My code looks like:
var updtUser = UserManager.FindById(model.UserId);
updtUser.UserName = model.PrivateEMail;
var res = await UserManager.UpdateAsync(updtUser);
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
updtUser.UserName,
DateTime.Now,
DateTime.Now,
false,
"someData",
FormsAuthentication.FormsCookiePath);
string encTicket = FormsAuthentication.Encrypt(ticket);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
return RedirectToAction("RedirectToDashbord", "Dashboard", new { area = "CRM"});
But after this manipulations HttpContext.Current.User.Identity.Name is not changed. Any help would be great
You should enable immediate revocation of cookies (+):
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromSeconds(0),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});

Owin, WebApi, and UseCookieAuthentication

I've configured OWIN in my ASP.NET MVC application using cookie authentication, but when I attempt to access an ApiController with an Authorize attribute on it, authorization fails and I can't figure out why. Stepping into the IsAuthorized method of the Authorize attribute, I can see that none of the identity properties that are present when accessing an MVC controller are present, so it certainly appears (at least to the authorize attribute) that the user is not authenticated.
The app is configured as follows:
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(MyAuthContext.Create);
app.CreatePerOwinContext<MyUserManager>(MyUserManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<MyUserManager, MyUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
var httpConfig = new HttpConfiguration();
WebApiConfig.Register(httpConfig);
app.UseWebApi(httpConfig);
}
Do I absolutely have to use bearer tokens for WebAPI or is there just something I'm missing.

ExpireTimeSpan ignored after regenerateIdentity / validateInterval duration in MVC Identity (2.0.1)

Been scratching my head all day on this one. I'm trying to set up "very long" login sessions in MVC Identity 2.0.1. (30 days).
I use the following cookie startup:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
SlidingExpiration = true,
ExpireTimeSpan = System.TimeSpan.FromDays(30),
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/My/Login"),
CookieName = "MyLoginCookie",
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
Which on the whole, works fine. The cookie is set 30 days hence, all looks good.
If I close browser and come back after "validateInterval" duration has passed (30mins here) I'm still logged in, however the cookie is now re-issued as "session" only (correct cookie name still)! The 30 day expiration is gone.
If I now close browser/reopen again I'm no longer logged in.
I have tested removing the "Provider" and all works as expected then, I can come back several hours later and I'm still logged in fine.
I read that it is best practice to use the stamp revalidation though, so am unsure how to proceed.
When the SecurityStampValidator fires the regenerateIdentity callback, the currently authenticated user gets re-signed in with a non-persistent login. This is hard-coded, and I don't believe there is any way to directly control it. As such, the login session will continue only to the end of the browser session you are running at the point the identity is regenerated.
Here is an approach to make the login persistent, even across identity regeneration operations. This description is based on using Visual Studio MVC ASP.NET web project templates.
First we need to have a way to track the fact that a login session is persistent across separate HTTP requests. This can be done by adding an "IsPersistent" claim to the user's identity. The following extension methods show a way to do this.
public static class ClaimsIdentityExtensions
{
private const string PersistentLoginClaimType = "PersistentLogin";
public static bool GetIsPersistent(this System.Security.Claims.ClaimsIdentity identity)
{
return identity.Claims.FirstOrDefault(c => c.Type == PersistentLoginClaimType) != null;
}
public static void SetIsPersistent(this System.Security.Claims.ClaimsIdentity identity, bool isPersistent)
{
var claim = identity.Claims.FirstOrDefault(c => c.Type == PersistentLoginClaimType);
if (isPersistent)
{
if (claim == null)
{
identity.AddClaim(new System.Security.Claims.Claim(PersistentLoginClaimType, Boolean.TrueString));
}
}
else if (claim != null)
{
identity.RemoveClaim(claim);
}
}
}
Next we need to make the "IsPersistent" claim when the user signs in requesting a persistent session. For example, your ApplicationUser class may have a GenerateUserIdentityAsync method which can be updated to take an isPersistent flag parameter as follows to make such a claim when needed:
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, bool isPersistent)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
userIdentity.SetIsPersistent(isPersistent);
return userIdentity;
}
Any callers of ApplicationUser.GenerateUserIdentityAsync will now need to pass in the isPersistent flag. For example, the call to GenerateUserIdentityAsync in AccountController.SignInAsync would change from
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent },
await user.GenerateUserIdentityAsync(UserManager));
to
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent },
await user.GenerateUserIdentityAsync(UserManager, isPersistent));
Lastly, the CookieAuthenticationProvider.OnValidateIdentity delegate used in the Startup.ConfigureAuth method needs some attention to preserve the persistence details across identity regeneration operations. The default delegate looks like:
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(20),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
This can be changed to:
OnValidateIdentity = async (context) =>
{
await SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(20),
// Note that if identity is regenerated in the same HTTP request as a logoff attempt,
// the logoff attempt will have no effect and the user will remain logged in.
// See https://aspnetidentity.codeplex.com/workitem/1962
regenerateIdentity: (manager, user) =>
user.GenerateUserIdentityAsync(manager, context.Identity.GetIsPersistent())
)(context);
// If identity was regenerated by the stamp validator,
// AuthenticationResponseGrant.Properties.IsPersistent will default to false, leading
// to a non-persistent login session. If the validated identity made a claim of being
// persistent, set the IsPersistent flag to true so the application cookie won't expire
// at the end of the browser session.
var newResponseGrant = context.OwinContext.Authentication.AuthenticationResponseGrant;
if (newResponseGrant != null)
{
newResponseGrant.Properties.IsPersistent = context.Identity.GetIsPersistent();
}
}
This bug is fixed in ASP.NET Identity 2.2. See https://aspnetidentity.codeplex.com/workitem/2319

Resources