Blocking all http requests if digital certificate is not present - asp.net

In my app, the user can be authenticated with a login/password stored in a database or using its digital certificate.
In both ways, if the login succeeds a cookie is created and associated to the user.
FormsAuthentication.SetAuthCookie(model.UserName, false);
return RedirectToAction("Index", "Home");
I need this to be different.
If a user logs in with its digital certificate, I want to check if the certificate is there
otherwise it throws an error.
The concept is if the certificate is not there, this is because the user has left so nothing can be done.
Is that hard to do?

I found a simple solution to this.
On IIS, there is a way to set in the site advanced settings the connection time-out.
It is the period of time (in seconds) a connection can remain inactive before being disconnected.
Click on the site node, in actions pane click Advanced Settings, click the + on Connection Limits and set Connection Time-out (seconds) to the period of time you find relevant.
I set to 1;
Now basically every time the user calls an action it checks for the certificate. If it is there, the application continues normally.
It has worked for me because the digital certificate is a requirement. For those with normal login / password form auhtentication you need to find a better way or the user will be always redirected to the login page.

Related

Restrict Multiple Login of same user across 2 Web Applications

We have got requirement to restrict concurrent login of same user across 2 Web Applications.
We have 2 Web Applications for example: WebApp1, WebApp2.
User: Dashboard
If Dashboard user is logged into WebApp1 then the same user is not allowed to login to WebApp2 instead show error message on second login.
Tried Solution:
Block 2nd login with same user id if there is an active session and show error message to user.
The idea is to maintain user id, Application Name and session id in DB. On second login of same user check if record exist in DB table against the user id then block 2nd login and show error message to user.
Clear the DB record (UserId, Session Id, and Application Name) in following
scenarios:
Logout
Session Timeout
Restart of Application.
Not Sure how to handle below scenarios.
Close Browser.
Browser Crash
System Crash
If 2nd login request is from valid user then Admin should able to Invalidate the session of first login as this user is attacker.
what is best way to invalidate Http session of WebApp2/ WebApp1?
If you really need to know the state of the first session, I would skip trying to manage sessions in the server, and instead maintain a heartbeat from the client. Have the client make a request every 5 seconds to the server which updates a "Last Seen" record, which includes their IP address and which app they are from, and whether "Last Seen" was a logout event.
Then the other app can interrogate "Last Seen", and if it's more than 5 seconds (I'd actually bump it to 10 for the interrogation), or a LogOut event, assume that the first session went away, and that they are free to log into the second application. If "Last Seen" is less than 5-10 seconds, bump them both out and alert the admin with both the IP Addresses to decide which one should be killed.
In addition to what you have, you could save last activity time in your session DB, and update it, when there is a session update, how often ( every request or once in 5 min for example) it depends on your requirements. Then in case of app/browser/system restart, you log in user, even if record exist, if it is older that session timeout. And you can have admin user that can manually delete entry if required.
The other solution would be to always log in new app, and logout the old one. But that would require introducing additional logic in the application to check if session is still valid.

Asp.net How to update sql table column if unexpectedly PC was shutdown

Scenario: I am working on website in which user login and do some tasks and logout. When user login in website I put a true value in database so other user is not logged in with the same username and password.
Problem: Above scenario was working fine. But I a face problem when unexpectedly PC was shutdown and that true value is there which I put in database on the first time when user login in my website. And the first user is unable to again logged in from same PC.
What I want: I need a mechanism in asp.net in which When unexpectedly PC was restarted / shutdown server automatically update my column in sql.
You can't use server code to monitor client machine behavior.
I suggest you re-design the database with a expiring time session, which will handle the login event when "true" value is on but user try to login again.
Another the way could be allowing users to "unlock" themselves, by email-reset token, or by secret password.
When user login in website I put a true value in database so other
user is not logged in with the same username and password.
It is not a good design, because internet is not reliable. You are very closed; instead of Boolean value in database, you want to store a token.
Solution
You need to redesign the system based on cookie (or you can also use bearer token).
When a user login, create a new token and store it in both database and cookie.
When a user request a page, validate submitted cookie with the one in database. If they are not same, ask the user to re-login again.
I need a mechanism in asp.net in which When unexpectedly PC was restarted / shutdown server automatically update my column in sql.
SignalR can help. On your website you have a HUB, that hub can detect when users connect or disconnect. Just map when disconnect is called and set that user in the database to false.
I agree with previous comments that it's a poor design. But SignalR can work around that for you.
http://www.asp.net/signalr

How do I silently request a specific SSL client certificate

I have an ASP.NET MVC5 site that uses forms authentication, but is also using client certificates for an added layer of security by setting:
<security>
<access sslFlags="SslNegotiateCert" />
</security>
The client certificate is optional because it isn't required until the user actually attempts to log into the site. When the user attempts to log in, the site will validate the Thumbnail, Issuer, and compare the Subject to the user attempting to log in (there will be a different certificate per user).The problem is that every time a user comes to the site they are prompted to provide a client certificate when they first enter the site, which may cause issues if:
they accidentally select the wrong certificate
want to log off & log back in with a different user (not re-prompted for a cert)
Is there a way to silently\automatically detect a client certificate based on the log-in provided rather than having the user select a certificate on first entering the site?
EDIT: Adding more specific example of Actual\Desired behavior
Actual Behavior:
User opens up Chrome and goes to http://www.example.com
Chrome pop-up asks user what client certificate they want to use
User chooses "user3 (www.example.com)"
User sees unauthenticated home page view & clicks the "Log In" button
User enters Username: "user2" and Password: "****"
Site validates that ClientCertificate.Subject == Username (fails because certificate is for "user3")
Desired Behavior:
User opens up Chrome and goes to http://www.example.com
User sees unauthenticated home page view & clicks the "Log In" button
User enters Username: "user2" and Password: "****"
Browser does something to silently detect if client has certificate "user2 (www.example.com)" with little to no user interaction
Question: Is the "Desired Behavior" possible in some way? (header? javascript? browser plug-in?)
By default, and due to security issues, there is no way to select a certificate for the user at all when he is visiting a website.
The user can configure their browser to use a specific certificate for a website by default if he wants, but that's a different thing.
For the second part, the certificate is used to secure the connection between the browser (client) and the server, so if you want to use another certificate you should entirely finish the connection between the browser and the server, unfortunately you would need to close the browser and open it again for that to happen in most cases. Or by cleaning the certificate cache, but that needs to be done manually by the user in his browser.
You can find a very good explanation about how certificates and SSL works here:
https://security.stackexchange.com/questions/20803/how-does-ssl-work
I am not aware of a way to do this within a single application. One way to do it is to create two asp.net-mvc applications. The second site would be a sub-directory application with the SslNegotiateCert in the sub-directory's web.config and contain all the secure methods/logins etc.

SQL Server Storing session state seems not to be working?

I've configured SQL Server to store session state (from here).
All I want to do is that when the user has logged into my application via browser A, I see that logged session when I visit my app from the browser B.
Right now that scenario doesn't work, I must log in one more time.
When browser B is opened (assuming it's a different browser altogether or a new instance of the same browser) a new session is created; therefore, what you see is expected behavior.
Also, I assume you mention this because you store in session some sort of key that indicates that the user has logged in successfully, correct?
If you want this behavior, you'd need to send some sort of authentication cookie with a long expiration date, you'd then read the cookie on the login page and consider the user as successfully authenticated, but keep in mind that this is a potential security risk.

the latest logon session is retained and the user is automatically signed out from the other session

Let suppose, I am building an asp.net website which has login scenario in it. I want to provide a certain functionality to the website that if the user is already login on computer 1 and now try to login on computer 2, so he will be allowed to remain login on computer 2, while automatically logout him from computer 1.
I also know that http is a stateless medium, so whenever user interact with computer 1 and try to interact with the page, it will get noticed at that time.
You need to store the additional data (the computer currently 'logged in') in the database, or application state. Then when you process the authentication request - check to see if the machine you stored matches the one requesting authentication - if it does not, you would force the user to log-in and store the new computer (ip address) in the database/application state.
In case Tony's suggestion does not fulfill your purpose, You need to generate a hash comprising of "UserLoginName" + "HOST_NAME" +"TIME" (or any combination you like) and store that hash in your Database against that loginName and also send that hash to the user in a Cookie.
On subsequent request you can check through a handler or module if that specific cookie is submitted and contains the value matching your database, if it matches then the user is coming from the same machine and no need to update anything , if not user is coming from some other machine either the cookie shall not be there or would be containing some other hash value so you should send him to Login page again and upon login just recreate the hash and update it in your database against his login.
Hope this shall work.

Resources