Is there anyway to identify Asp.net identity token expiry timeout event or idle timeout event.? - asp.net-mvc

We have created an Identity server 4 application for single sign-on in Asp.net core 2.0. We use the Microsft Identity framework for login and account related pages.
The client applications are created using .net FW 4.7.1 in MVC 5 which are then connect to identity server for single sign-on purposes (used Identity server 3 in client application).
We have a requirement wherein allow users to log in to the application only from a single device at a time. To achieve this, on user login, we create a unique LoginSessionId and store it in DB. On logout, we just make this session-id null.
If someone else tries to login with the same user on another device, we just check if the LoginSessionId has value. If yes, then we give a message informing the user that he's already logged in on another device and if he wants to kill the other session. If he says yes, we let him login and reset the LoginSessionId with a new one. As for the first device login, we have a check-in place to log out that user if his current LoginSessionId does not match the one in DB, so he gets logged out.
We have also set the AccessTokenLifetime and IdentityTokenLifetime of the identity server-client application to 24 hours. Here is the problem we're facing:
When the 24 hours are up after user login, the user gets logged out since the Token must have expired. But the LoginSessionId mentioned earlier is not reset. Thus when a user tries to log back in, we end up showing the message of another user logged in, which is not really the case. Question is,
Is there is any way to raise the token expiry event so that we can clear the LoginSessionId there?
Is there any common place where we can identify the various reasons due to which user gets logged out. Like was it due to token expiry, or because he was idle for a long time (sliding expiry I think), or if he clicked logout himself etc.
What is the max value that we can set for AccessTokenLifetime and IdentityTokenLifetime.

One needs to implement IEventService and IEventSink in Identity Server 4 to get those evnts.
for more details, you can refer to this link.
link

Related

Social login keeps the provider app logged in

I visit an app that uses oauth social login
I choose say gmail; I get sent to gmail site
I log in to gmail and then get sent back to the app
When done with the app I log out
After step 4, even if I close the browser and open anew, visiting gmail opens my account straight away without prompting for a password. Keep in mind, I never let browsers save my password neither do I ever tick “remember me”
I’m not sure the average user will remember to visit gmail separately to log out; this would be disastrous on a public computer.
My question:
Is this a design flaw of oauth2 or is it an implementation flaw with the app in step 1 or is it an implementation flaw with google-login? Or is it technically impossible for the app in step 1 to log out of the social identity provider (in which case it’s not a flaw at all.)
The OpenID Connect core spec and the session management spec defines ways to both:
Sign the user out of an identity provider (link)
And force user re-authentication with the OP after a maximum
authentication age (max_age) has elapsed since last user
authentication. (link)
Trouble is I'm not sure if Google implement these things see this
I've tagged your question with OpenID Connect as authentication is not an OAuth2.0 concern.

Desire2Learn Revoking User Keys

I am unable to revoke application access by a user via either a password reset or by explicitly clearing app keys in user management. The latter method gives a reply indicating that access has been revoked, but when the user hits the tool, they are not re-prompted to approve access to their information.
There are number of possibilities here:
It's possible that there is latency between the declared revocation of keys and the cleanup task that goes through the database and actually cleans them up; I believe that at one point, such a latency existed, was identified, and fixed through service packs and subsequent releases. Accordingly, you may address this issue by ensuring that your back-end service is up-to-date with its available service packs.
It's possible that what's being revoked is the keys, and the necessity to authenticate to rebuild keys, but not the confirmation step that would appear to the user asking for access permission (assuming the user once authenticated, and checked the "don't prompt me to ask for permission again") dialog.
Can you confirm if the request for user tokens by the client application actually does get back tokens? Or is it just that the authentication step happens with no notice of client confirmation to access?
Note that the re-authentication might appear to happen silently; if the client application's request for user tokens happens through a user's browser context where the back-end service can determine that the user is already logged in to the LMS, then the request for tokens could succeed automatically:
The user is assumed to have already authenticated in order to have an active web session, so there's no need to re-gather a username/password (or whatever user auth step the LMS uses) to re-confirm identity.
The user may already have confirmed access for the application and dismissed the confirmation step with "don't ask me again". If the user has confirmed access with "don't ask me again" this choice will get remembered, even if the user tokens get expired due to password change or access revocation by an admin.
If you explicitly log a user out of their LMS session, and then test the client app, this should indicate to you visibly whether the re-authentication step is actually taking place (the user's browser will then get directed to the login process for the back-end service).
Note that, although a user password change or access revocation by an admin can remove the recorded user Id/Key pair associated with an application, it does not remove the record of the confirmation form having been dismissed with "don't ask again". Currently our system does not expose a way to reset that confirmation state.
If after considering these points you feel you still have an issue, I would encourage you to open a support incident through your organization's approved support contact, or your account or partner manager. Desire2Learn takes security related reports quite seriously, and if you've uncovered an issue that hasn't yet been addressed, I would encourage you to report it as a defect.

Soundcloud as Oauth Provider: How to make it connect only one time

I'm currently implementing an Oauth consumer service which is going to use Soundcloud as an Oauth service provider as well. But I'm having the following issue with it: Taking Facebook or Twitter example, you go there, you sign in, you fill up the permission form, and you are redirected back to your app. If you go there a second time, and given you are already sign in, you basically skip all steps and are redirected back instantly. That means, Facebook recognized that you already gave permission to that 3rd party service, so it doesn't ask your permission constantly.
And that's what's happening when I use Soundcloud. Basically everytime I redirected the user to the Soundcloud Oauth connect endpoint, the permission form always shows up, even though I already gave permission to that 3rd party service previously. I'm forced to press "connect" every single time, which is a drag from the user perspective (how many times can you give permission to the same entity). My question is: is there a parameter I can use to make soundcloud recognize/validate the previous permission from the user account to that specific 3rd party service? Or is this Soundcloud Oauth design implementation and we have to live with it?
Edit:
Maybe this wasn't clear, but each time I press "connect" in soundcloud, a new access token is being generated and delivered. Since my app uses this access token to identify its users, it doesn't work very well for me that the access token is getting updated everytime I want to log in, making me effectively "sign up" everytime. To sum it up, I want to get the previously attributed token to my account, so I can look up in my database, identify it and log him in.
I'm also looking for a solution which doesn't involve storing state in the client that might get cleaned up.
What you can do is store the user's oauth token in local storage and reuse it in future sessions. That's what happens on soundcloud.com.
A longer explanation:
When you use the Connect flow, the user is authenticated by SoundCloud (either by using username/password, Facebook Connect, or an already-existing session on soundcloud.com), and then when it is successful, your app is given an oauth token for that user. This is passed to the callback page which is registered for your app.
That token is the only piece of information needed to have the user be "logged in". Unless the token expires (by time, or by the user manually revoking it), then you can reuse that in future sessions.
I think I'm a bit confused about your application's design: where and how is the oauth token being used? I think that instead of using the token as an identifier, perhaps the user's permalink might be better? If you have the oauth token, you can find out the permalink by querying api.soundcloud.com/me.

ASP.NET MVC ActiveDirectoryMembershipProvider user stays logged in even when password has changed

I am using ActiveDirectoryMembershipProvider in my web app. I authenticate users with their domain credentials like so
if (Membership.ValidateUser(m.Username, m.Password))
FormsAuthentication.SetAuthCookie(m.Username, true);
This works well.
But even when the user's password is changed in active directory, the user stays logged in to the web app?
How can I ensure the user does not stay logged in to the web app if their domain password changes, or their account is disabled etc?
The answer is to periodically (every 30 minutes or so) check User.IsApproved and User.LastPasswordChangedDate to make sure the users credentials are still valid.
To do this you need to manually create the FormsAuthenticationTicket and cookie, rather than using FormsAuthentication.SetAuthCookie.
Put the date you validated the user inside UserData and compare this against LastPasswordChangedDate.
I've implemented this and it works perfectly.
More information here
Check if Active Directory password is different from cookie
I'm not 100% certain, but it sounds like you're unhappy that the user's auth ticket continues to work even though their password changes / account expires.
Once a user has logged in and has a authentication ticket (cookie), the user is not challenged for authentication again until until the ticket expires (set in the web.config file). Here are 2 suggestions for dealing with this problem:
Wait for the auth ticket (cookie) to expire. Upon the next login, the user will
be required to use their new password. Variations of this solution include using session-only cookies so that the user must always login when the browser is closed (recommended for AD authentication).
Write an Http Module that looks for a list of recently updated users and inspects the auth ticket early in the HTTP pipeline. If an auth ticket comes through and matches the list of updated users, you exprire the user's cookie and re-direct them to the login page. Here's a similar question that would help get you started:
How can I force a logout of all users on a web site

DotNetOpenAuth Login without asking credential in second Time (if less then 10 to 15 Sec)

I'm using DotNetOpenAuth. I configured my application with Custom form authentication with Gmail OpenID through (DotNetOpenAuth). I can successfully login to my app. But say for eg. i logged out from application and click login (with in 10 to 15 Sec) its not redirecting to gmail login. It generated authentication token by itself without asked from user.(I hope something is cached OpenID)
I used PAPE
request.AddExtension(new PolicyRequest()
{
MaximumAuthenticationAge = TimeSpan.Zero
});
And also tried to configure in web.config.
<openid cacheDiscovery="false">
Is there any workaround for the same.
NOTE : Once i logged out i used to clear ALL Session and call FormAuthentication.SignOut()
With OpenID, you as the relying party cannot force the login policy for the user at their Provider. You can request that the provider relogin the user as you have with the PAPE extension, but the Provider may still ignore that.
The cacheDiscovery setting is irrelevant to pass-through login, so I suggest you remove that entry as it will simply slow down all logins.
I think you're mistaken when you say it's not redirecting to Google. If you look at the logs, or what your browser's URL bar, Google.com should be redirected to, but at that point Google decides the user has a login session and avoids prompting them to login again, and redirects the user immediately back to your site.

Resources