Good day,
Is the following a good solution or is there alternative or is this bad.
I have a ASP MVC client application and it talks to a HTTP API (also Microsoft but does not matter).
In my client application I'm storing session data (HttpSessionState) for data the user is busy with (cache). Obviously the session data is stored against a session ID which is the instance (session id per client browser). My first problem to overcome is I need to store data using a Unique key for the user (application user) so that I dont override or remove cache if theres more than one logon in the browser. I might have internet explorer open with multiple sessions to the application. This might be the same user two instances or two sessions different session.
When I authenticate the user I have a ID/webtoken. Could one use this as the identifier and store cache with that key included, So if the user logout the cache is clear only for that "logon". Remember this is HttpSessionState which is stored on the server not client browser.
You will not be able to login to two different user accounts in one session as you have only one Authentication cookie shared between all your open tabs. If you open another session, no matter if the user is the same or different you will have a different session id so you will refer to a different session data.
Also remember to secure your WebAPI using tokens as cookie authentication is not recommended and valuable for XSS attacks.
Related
We have a SPA application that makes use of cookie-based authentication. The cookie is validated on the app server by checking the expiration time of the user's stored session in a database.
The client requirement is that each new tab/browser opened should force the user to log in on that new tab/browser instance, thus allowing the user to have multiple sessions open for concurrent work purposes. Closing a tab or signing out needs to expire the user's session for that specific tab and still keep the other sessions active. Refreshing a tab should obviously still keep the user logged in on that specific tab.
At the moment, we make use of a unique identifier to identify the specific tab with its accompanying cookie, in order to only clear the relevant cookie when the user logs out or closes the tab. This unique identifier is stored in Session Storage and gets passed as a header with each server request. This unique identifier is visible in the the browser URL, for the reason that when the tab is refreshed, that identifier is used to get the relevant cookie and authenticate it.
This whole process feels clunky and prone to bad security practice.
What type of authentication would be best to facilitate the client requirements?
It feels like a very old-fashion and outdate requirement, to have separate sessions per tab. One approach is to let the backend redirect each new request to it, to its own unique per-tab sub-domain, so that each sub-domain can get its own independent set of cookies.
like
session1.mysite.com
session2.mysite.com
session3.mysite.com
session4.mysite.com
session5.mysite.com
Consider the setup where a list of ids and passwords are stored in a database on a server and when a user enters his login credentials then the code-behind verifies it against the server and sets values like Session["id"] Session["login"] to determine whether user has access to certain page.
When a user attempts to browse to a page, the page looks at session variables and then relocates the user if need be and adjusts the buttons on its page accordingly.
How secure is this setup.
The built in login and role functionality of asp.net seems too rigid so I was trying to explore other options.
The major flaw in using Session is that it could open up your site to a Session Fixation vulnerability. As the session is established when the user arrives on your site, it may be possible for the session ID to be discovered (e.g. by a MITM).
Example steps are as follows for this exploit:
User arrives on HTTP site, ASP.NET gives them a session and sends the session cookie to user.
Attacker reads the session cookie value.
User goes to login form (HTTPS), logs in and your id and login values are stored in the session.
The attacker sets their session cookie to be the intercepted value from step 2.
The attacker now has a valid, logged in session, hijacking the now logged in user.
For this reason alone, I would recommend using the built in login and role functionality as the auth cookie is not set until the authenticated session is established. If you insist on the session method, I would recommend you call Session.Abandon() to grant the user a new session upon login, so that their session is not the same as their previous, unauthenticated session.
Please also see my answer to this question: https://stackoverflow.com/a/18077422/413180
The Session State is a safe way to keep track of user log-ins. Assuming the default set-up (in process, cookie-based session), it will be just as secure as Forms Authentication. The exact level of security you get with it will depend on how you configure your Session State.
Cookieless session state -- this opens up some potential security loopholes (e.g. user shares the url that contains the session ID, user takes a screenshot that contains the URL with the session id, etc.)
Out of process session state -- If you are using a remote session state service (or a database for storing the session), your Session's security will depend on you locking down access to the session state service or DB appropriately.
That said, the built-in login and role functionality that you get with Forms Auth is not too difficult to extend and build upon, rather than rolling something from scratch. If you need something custom, you can also write your own membership and role providers. This is helpful if you need to lock down routes based upon user name or role, as you can do it right in the web.config.
I'm writing an application which displays a login form before it loads, and it sends a POST request to a web application which I previously developed.
I can send login details off and get returned a 200 message and can recieve data within that request. However I now wish to store this login after the application has closed, to allow the user to not have to login every time they open the application, or in this case when the computer is restarted. (It will run at boot however needs to maintain an application and not a WCF service)
I'm using HTTPWebRequest in C# to handle POST requests to the server, and I can make cookies on the server side. How do I let my application know about these cookies and store them in a secure way to allow persistent login for my entire application? I've looked at a number of ways to store cookies in C# such as these two links:
http://www.c-sharpcorner.com/uploadfile/mahesh/managing-cookies-in-a-wpf-application/
http://msdn.microsoft.com/en-us/library/dd920298(v=vs.95).aspx
However the code in the first link gave me an odd cookie:
"CSCUser2=test-username; android_developer_C:_width=243px; __utma=1.1718972007.1316996246.1316996246.1316996246.1; __utmz=1.1316996246.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); android_developer_reference_lastpage=/C:/AndroidSDK/android-sdk-windows/docs/reference/android/speech/RecognizerIntent.html"
So I'm not sure if that approach is best? Any pointers would be appreciated.
I think the CookieContainer (i.e. the MSDN link) is the correct way to set and get cookies (By the way: note that your question has nothing to do with wpf or mvvm patter. It is a general c# /.net/httpwebreuqest topic).
As for caching credentials on the user machine which can be used in subsequent sessions - there are several ways to do this. You can either store the user password in a secure location, or you can store a session key sent to you from the server. The advantage of the second method is that the session key is limited in time (e.g. one week), and after that they user will have to perform a new login. The session key can be delivered to you from the server out of band as a cookie, or with a specific API. Web applications are using cookies because they have no access to any persistent store, but your wpf application can store the password or the session key anywhere it wants.
I recommend you use the DPAPI to persist secrets on the user computer. Google for c# and DPAPI to see how to do it in .net.
My asp.net session objects are storing in SQL server.I am storing an ID in session. If client open another browser and storing different ID in session. I need to notify client is “are you sure you want both ID’s open?” in same based user logged user.
Application runs on logged in user (not anonymous)
How can we check this in asp.net?
Session is not linked to an authenticated user, and there is no way of accessing an other connection's Session without knowing its SessionID.
Usually this kind of problem can be solved using cache instead of session state. With cache you can create your own user-based keys to store data. Depending on whether you are planning to just run your web app on one server or in a web farm environment, you can either use asp.net in-process cache or one of numerous distributed cache solutions (like memcached which I'm using in my web projects with great success).
There are a couple ways to go about this:
Option #1, in your user table, add a value called "session id"
When a user logs in, check to see what their last session id was. Then test to see if it's still a valid session. If it is, ask them what they want to do. Store the latest session id in that table after each log in.
However, I'd go with option #2: Don't do this. If the user wants to open multiple browser windows to access your application then let them. There's probably a pretty good reason for it. Most (as in nearly all) users have no idea what "session state" even means and they really have no desire to know. All they care about is getting their job done.
I was wondering if anybody could give advice on a secure way to implement a global login. I have an admin page that accesses active directory admin groups after typing in your username and password.
current logged in account (on computer) does not matter
user in web browser goes to web app, redirects to global login page with query string of app name
types user name and password of an account in AD (not necessarily current computers logged in user)
authenticates (looks up user, pass etc and authentication is valid)
redirects back to original web app.
Once redirection happens, how do I securely tell the original web app that this user is ok until the original web session dies?
The way I'm thinking of implementing it:
My original thought was to pass the session ID of original app to the login page as well as the app
name. Store that session in a DB once authentication is checked. Master page of the other app validates on page load that the session ID matches. On session close, remove current session ID from DB.
You cannot depend on sessionID accurately in some cases. SessionID only becomes a constant value after a (any) page makes a request for a session variable, if you dont have Session_Start not defined in global.asax. If you log the user in and the default page does not access session, you will end up with a different session id for the subsequent requests until a request to session is made. Usually it is always constant as there is a default empty session_start event in global.asax.
But similar to your model, you could generate a GUID (or make sure you access session on login/authentication) and store it in the user table with an expiration. Your web sites can check this key and if currently valid, auto sign the user in.
You also cannot depend on session_end event since there is no real accurate way of detecting it (eg: user closing browser). So, you should store this ID with an expiration time along with it, preferably the same as session timeout. Just like session, you will need to extend this, something like a sliding expiration. This way, this id will be expired after a period of inactivity.
also, this Claims-Based Single Sign-On for the Web may be of interest to you.
What you're describing sounds like it would be better implemented using Windows Identity Foundation and Active Directory Federation Services 2.0. I don't know the extent of all your requirements, but it might be valuable to check out what these will give you out of the box.
You could use a cookie. If you pass the name of the application to the login page, you can set that application name to the PATH property of the formsauthentication cookie. By setting the PATH property, you're effectively limiting the readability of the cookie to the pages within that path. Because it's a common login interface, this may require some code being done perhaps in a common page base class that handles the parsing of the cookie information.
You can share authentication tokens between .NET applications, even between .NET CLR's if you want to. I think this will give you the single sign on you're looking for.
At a high level you need to share a machine key between the applications. You can generate the machine key using the key generator app code example found on this link, and providing you then reference the same key in each application the sign on can be shared:
http://msdn.microsoft.com/en-us/library/ms998288.aspx
There are some consideration when looking at things across domains or accross machines/web farms etc, but if all apps are on the same box it's not too hard.
The harder side of things is sharing things like session state which I don't believe can be done accross app pools. (I ended up recreating the session object on the new app manually last time I did it :( but that was between 1.1 and 2.0 apps )
EDIT: I did a rough write up of it last year and was using it as a test for a demo article on my site, might be worth a read through if you want things broken down a bit more (Ignore the unfinished site!):
http://www.dougmcdonald.co.uk/test/html5/v5/articles/2010/05/10/Sharing-forms-authentication-between-applications/