Identityserver3 - Client application session timeout - session-cookies

I am using Identityserver3 as my IDP. my RP is an MVC5 .net web application. The web application uses the idtoken to create its authentication cookie. It passes the access token to authenticate to a Web API over Rest calls.
My idtoken is valid for 5 minutes
My access token is valid for 60 min
Once the user authenticates himself, the auth_cookie lifetime is 20 minutes with sliding expiry.
My web application startup code as below -
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
CookieHttpOnly = true,
CookieSecure = CookieSecureOption.Always,
ExpireTimeSpan = TimeSpan.FromMinutes(sessionExpiryMinutes),
SlidingExpiration = true
});
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
Authority = authority,
ClientId = clientId,
ResponseType = responseType,
SignInAsAuthenticationType = "Cookies",
Scope = scope,
RedirectUri = redirectUri,
PostLogoutRedirectUri = redirectUri,
UseTokenLifetime = false, .....
When the user remains idle for 20 minutes, the application cookie expires, user is redirected to identity server and new cookies are issues.
The issue comes up when the user keeps the session active and if the user is active on the 60th minute, the Access Token expires and the API that consumes this access token issues A 401 to my Web application. At this point the web application's cookie is still valid but its unable to communicate to the API since the access token is invalid.
Am i doing the right thing here? Shall i signout the user if the access token expires or shall i extend the access tokens validity to a longer duration say 5 hours to fix this issue? Or shall i make the cookie non sliding? A non sliding cookie would confuse the end user since, he will be using the application and he will be suddenly redirected to the IDP
EDITED: I use the implicit flow and hence i couldn't avail the refresh token.

Related

Re-authorization for an app to send gmail

under what situations (other than someone revoking permission of changing their gmail password) would a user need to re-authorization an app's access to their gmail data? My app stores and uses a refresh token to maintain a current access token, but my users are occasionally still asked to authorize from scratch, and sometimes this then fails and only works again when they reset their browser settings.
Causes for a refresh token to expire.
user revokes access.
User changes password and your using a gmail scope
refresh token has not been used in six months.
You can have a max of 50 outstanding refresh tokens for a user. So if the user is requesting a new refresh token often make sure to store the newest as the once you hit 51 the oldest one available will be expired.
That should be about it unless you consider the bug of fall 2015 which caused a bunch of refresh tokens to expire due to daylight savings time. (That was a fun day)
I'm not storing anything explicitly, it's all being done by Google's Authorization Broker. Here's the code:
UserCredential credential;
using (FileStream credentialsfile = new FileStream(Application.StartupPath + #"/credentials.json", FileMode.Open, FileAccess.Read))
{
string credPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/SJGmailAPI.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(credentialsfile).Secrets, Scopes, senderemailaddress, CancellationToken.None, new FileDataStore(credPath, true)).Result;
}
bool rc = AuthTest.TestAuthorisation(credential,senderemailaddress,ApplicationName);
So is Google's own code storing the wrong refresh token then?

Adding Azure AD authentication to existing .Net MVC app: id_token not being validated

I'm trying to add Azure AD authentication to a .Net MVC app that currently uses individual user accounts. I've setup the app registration in Azure, and installed and configured OpenID Connect.
In Startup.cs I've added:
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
// app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// Sets the ClientId, authority, RedirectUri as obtained from web.config
ClientId = clientId,
Authority = authority,
RedirectUri = redirectUri,
// PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it is using the home page
PostLogoutRedirectUri = redirectUri,
Scope = OpenIdConnectScope.OpenIdProfile,
// ResponseType is set to request the id_token - which contains basic information about the signed-in user
ResponseType = OpenIdConnectResponseType.IdToken,
// ValidateIssuer set to false to allow personal and work accounts from any organization to sign in to your application
// To only allow users from a single organizations, set ValidateIssuer to true and 'tenant' setting in web.config to the tenant name
// To allow users from only a list of specific organizations, set ValidateIssuer to true and use ValidIssuers parameter
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true // Simplification (see note below)
},
// OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to OnAuthenticationFailed method
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed
}
}
);
And in web.config I've set authentication type to None
<authentication mode="None"/>
I've then added an action method to trigger the challenge:
if (!Request.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties { RedirectUri = "http://localhost:54465" },
OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
I can still login to the app with individual user accounts (I'd like to keep this as an option), but can't sign in with Azure AD. The user gets redirected to the Azure AD login screen, logs in, and I can see the response coming back with id_token, but never authenticates in the app.
I'd understood this is supposed to happen automatically within the OpenID Connect middleware, but is there anything else that needs set up?
Remember to set RedirectUri which is same with your app registered in azure ad.
I test with your code and could authenticate in the app. In Azure ad app registration, click Authentication and choose Id Token.
You could refer to this article and download sample about adding Microsoft identity platform sign-in to an ASP.NET web app.
I created a clean project using the same Azure app registration and it worked as expected, so started comparing the clean project against my old one. In the very early days of the project it used SimpleMembershipProvider, and even though the project had since been changed to use ASP.Net Identity the WebMatrix dlls were still being referenced and included in the build.
Removing these references, cleaning, and re-building has solved the issue.

Owin authentication sign-out is not invalidating Identity in asp.net MVC

I am connecting to QBO (Quickbooks Online) app using OAuth. QBO has it's own Auth Server and Auth Client.
I am using single sign-on. So after successfully connecting to QBO I am setting Cookie using following code:
var id = new ClaimsIdentity(claims, "Cookies");
Request.GetOwinContext().Authentication.SignIn(id);
My Startup.cs contains:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
AuthenticationMode = AuthenticationMode.Passive,
LoginPath = new PathString(Paths.LoginPath)
});
To signout I used :
HttpContext.GetOwinContext()
.Authentication
.SignOut(HttpContext.GetOwinContext().Authentication.GetAuthenticationTypes().
Select(o => o.AuthenticationType).ToArray());
But User.Identity remain valid after sign-out. I have tried different solutions from SO but no success.
Any idea?
When you call SignOut it would delete the cookie in order to invalidate user identity, but the User would be still authenticated during that request.
You can put [Authorize] attribute on the action that is signing the user out, so it will be redirected to login page.

Why log out sooner than ExpireTimeSpan in asp.net identity?

I am working on an asp.net mvc application that used asp.net identity.
In Startup.Auth.cs file I set ExpireTimeSpan to 20 days but when I log in to my app, sooner than 20 days my app is logged out and I have to log in agian!
Startup.Auth.cs
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/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, User>(
validateInterval: TimeSpan.FromMinutes(0),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
},
ExpireTimeSpan = TimeSpan.FromDays(20),
SlidingExpiration = true
});
And in Login action:
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: true);
Update
When I log in, .AspNet.ApplicationCookie is generated and it's expire date is set to "20" days later, And when I open site next day, I am logout but the cookie is exist.
What is the cause of this problem?
Thanks in advance.
Here are the few reasons for logging out sooner than expected:
Having multiple web apps on the same domain and all of them have the same cookie name (cookie name collisions). In this case app A overwrites app B's cookies.
When validateInterval is set to zero/TimeSpan.FromMinutes(0), all calls to UpdateSecurityStamp will force the user to logout and login again immediately, including UserManager.CreateAsync, UserManager.RemovePasswordAsync, UserManager.UpdatePassword, UserManager.RemoveLoginAsync, UserManager.ChangePhoneNumberAsync/SetPhoneNumberAsync, UserManager.SetTwoFactorEnabledAsync, UserManager.SetEmailAsync. Which means if you update the user's properties, UpdateSecurityStamp will be called.
If you update the .NET framework on the server, it will overwrite the machine-key too. changing that will mark all of the issued cookies as invalid. The Machine-Key is a set of keys used to encrypt and decrypt the cookies. If you are running behind a load balancer you will want to ensure that the web farm is using a consistent machine-key.
If you are storing too many user-claims with your cookies, they will become large (larger than ~5K) and some browsers will reject them. so check out the size of the issued cookie.
Users can set their browser to delete the cookies when they close it (private browsing).

WIF session token set through SessionAuthenticationModule lifetime

Please help me to understand the concept of expiry time for sessiontoken.
Below is the way I am setting the session token after receiving the token from STS.
var principal = validationfunction();//returns claimsprincipal
if (principal != null)
{
var token = new SessionSecurityToken(principal.ClaimsPrincipal)
{
IsReferenceMode = false
};
//this makes sure that the identity and claims are written to the cookie.
FederatedAuthentication.WSFederationAuthenticationModule.SetPrincipalAndWriteSessionToken(token, true);
}
Please confirm if this is true or not:
if the token lifetime is 10 mins. if user is inactive for 10 mins and doesnt send any request to
website it the session token expires and its redirected to STS login page.
if user is active and keep refreshing the page/visits different page the sessiontoken lifetime gets
refreshed . it means everytime the user visits the page the token gets new expiry value. So user will not be redirected to login page every 10 mins.
if user requests a STS protected resource (web api) , the life time of token is treated absolute. Meaning regardless user is active or not, after 10 mins of token generated if the user requests web api , the token will be invalid and redirected to STS login page.
are the above concepts correct?
You need to set the token lifetime yourself. The default is IIRC - 10h. When the token has expired and you are accessing a protected resource, the application will emit a 401. If you have the WsFed modue - this will result in a roundtrip to the STS
Session security tokens are absolute expiration by default
You wouldn't use a cookie to secure a Web API - a redirect does not make sense for APIs (nor does cookie authentication).

Resources