How does wininet handle cookies - authentication

I have a .NET client application that needs to communicate with a server using two distinct user credentials.
Lets say that the application runs two threads. When start running, every thread sends the user & password to authenticate and the server in return stores a cookie on the http session. The subsequent calls send the authentication cookie and not the user credentials.
We have two cookies for the same process. How does wininet "knows" to send the appropriate cookie for each thread?
Does wininet manage the cookies collection per thread? per http session? per process?
Thanks

Wininet uses cookies per process.
However in a .NET client you can use a Cookie container with the HttpWebRequest object.
You create one cookie container for each "session". Assign the appropriate container to each HttpWebRequest when making the various requests for each session.

Related

How authorize web application and manage sessions

I am building a single page react app that uses redux as state manager and an express node js as backend server, but I don't know what is the best way to authorize my users in the application!
If it was a php or express-js website, I could use PHPSESSION or express-session to manage users sessions data but now the single page web application is separated from the backend and I can't manage sessions like before!
My idea is to make a session id for each new web request, then save it for client in local storage, then in the server store all needed informations in a database and when application have an API call, send that id in request header. Then we can check authorizations by using that implemented session.
But I thought if there was a simpler way to handle this problem that has no need to make a session implementation by myself.
(I don't want to use third party services like firebase or okta or save all session data in client part like JWT.)
At the end i implemented a custom session manager ( SessionMush ) so the client send a request to server and get a token id then use it to access its session in server.
Each session should be accessible by an identification token ( here knows as sid ) so the application can save that token to access and use that session. A server side state for your application can be use for saving clients auth state or any temporarily data about clients that you want to use them on server side so in your application you will save that identification token and then with each request you will send it in http headers then the server will know who you are and what was you did before on the application based on that saved session data in database (server side state for that id) so it can serve the needed information for you based on the client identity and it's state on the server. It created to be used as a express middleware and mongodb as data store.
When your application have no session and it loaded for the first time it sends a request to the server to gain an identity for itself When the request received to the server, server analyze the request and it'll find out that there is not exist any session id (sid) so it will make a new one for this request and add it to response header part so when the server decide to send the response it will send that created session informations too. The client should save that informations to use that session for its other requests. it can send that id in the request header part to show its identification. A session can be expire too when it doesn't used for a threshold time. so when the server get wrong or expired session it will behave to it like a request without any session so it will create a session for that request and send its informations like what we explained before.

What does connectAs="endUser" actually do?

The Worklight documentation refers to an attribute within the element of an adapter's XML file called connectAs="endUser". It says that this means that:
The connection to the back end is created with the user’s identity.
Only valid if a user realm has been identified in the security tests
for this procedure.
However, what does this actually mean in terms of the HTTP connection that is performed from the adapter to the back-end HTTP server? How does it affect, for example, the JSESSIONID?
EDIT: Further to my original post, Anton Aleksandrov has provided a blog post with more details on how this mechanism works:
https://www.ibm.com/developerworks/community/blogs/worklight/entry/configuring_http_adapters_for_stateless_stateful_backend_connectivity_and_user_identity_propagation?lang=en
What this actually means is that the Worklight server will behave as if it were an "end user" (specifically, a web browser).
Within a given Worklight adapter, the connectAs="endUser" parameter will result in the HTTP Set-Cookie headers being stored as part of an authenticated Worklight session. Subsequent requests that request connectAs="endUser" will send any cookies that are stored as part of that "endUser" server-side session.
The Worklight documentation specifically states that it is only valid in a realm has been identified since if there is no realm, it is not possible to save those cookies for later use in the server-side session.
The effect from a Worklight client app point of view should not change if you choose to use this parameter.
The Worklight server to back end HTTP services will change. Essentially the back end server will treat a Worklight adapter that uses connectAs="endUser" as a single HTTP web browser. So for the example of JSESSIONID:
You initiate a procedure "login" for the first time that specifies connectAs="endUser". This procedure also has an associated security test which enforces a user to be logged into a realm (by whatever means, or anonymous - it doesn't really matter so long as Worklight has a user session to attach cookies to)
When this request reaches a Java-based server that tracks sessions by JSESSIONID, it will detect that this is a first-time request. It will process the request, and send a HTTP response, with whatever content is necessary in the HTTP body. In the HTTP headers, there will be a Set-Cookie response that contains a JSESSIONID.
By virtue of the Worklight procedure having contained connectAs="endUser", the Worklight server will process these Set-Cookie headers and store them alongside the session of the user authorised against the Worklight realm (this is why you need to have a realm that is logged in for this to work)
On a subsequent request to a procedure "mySecondServerProcedure", which also has connectAs="endUser" and the same realm specified, the Worklight server will automatically provide the stored cookies to the server on the outgoing HTTP request, in addition to any you add as parameters on a requestHttp() call in your adapter. In this example, the JSESSIONID that was set as part of "login" will be provided.
If you make another request to a procedure "myThirdServerProcedure" that does NOT have connectAs="endUser" set, no cookies will be provided to the server on the outgoing HTTP response that you do not provide manually as part of the "Cookies" parameters on the requestHttp() call in your adapter.
Important points to note:
A user must be logged in for this to work so that Worklight can associate the HTTP cookies with a session
The session cookie storage is only valid WITHIN the adapter that made the initial request; if you run a connectAs="endUser" request from another adapter after having gotten your JSESSIONID set as part of "login" above, this request will NOT have the JSESSIONID cookie automatically appended to the outgoing request.
If you log out of the authenticated Worklight user session, all reference to these cookies will be gone.
My general rule of thumb is as follows:
If you are doing some fairly simple authentication that requires cookies on the back-end server to remain consistent, use endUser
If you're doing something more complex, or potentially requiring the cookies sent by the server to be available from multiple adapters, find another way to store the cookies. A pattern I like is to have a wrapper method present that makes the outgoing HTTP request and processes the headers that come back in the response to store necessary "global" properties somewhere. In the Worklight world, this can either be as part of a Worklight user session object, or you can call out to an underlying Java or database storage implementation.

Authentication, Authorization and Session Management in Traditional Web Apps and APIs

Correct me if I am wrong: In a traditional web application, the browser automatically appends session information into a request to the server, so the server can know who the request comes from. What exactly is appended actually?
However, in a API based app, this information is not sent automatically, so when developing an API, I must check myself if the request comes from an authenticated user for example? How is this normally done?
HTTP Protocol is stateless by design, each request is done separately and is executed in a separate context.
The idea behind session management is to put requests from the same client in the same context. This is done by issuing an identifier by the server and sending it to the client, then the client would save this identifier and resend it in subsequent requests so the server can identify it.
Cookies
In a typical browser-server case; the browser manages a list of key/value pairs, known as cookies, for each domain:
Cookies can be managed by the server (created/modified/deleted) using the Set-Cookie HTTP response header.
Cookies can be accessed by the server (read) by parsing the Cookie HTTP request header.
Web-targeted programming languages/frameworks provide functions to deal with cookies on a higher level, for example, PHP provides setcookie/$_COOKIE to write/read cookies.
Sessions
Back to sessions, In a typical browser-server case (again), server-side session management takes advantage of client-side cookie management. PHP's session management sets a session id cookie and use it to identify subsequent requests.
Web applications API?
Now back to your question; since you'd be the one responsible for designing the API and documenting it, the implementation would be your decision. You basically have to
give the client an identifier, be it via a Set-Cookie HTTP response header, inside the response body (XML/JSON auth response).
have a mechanism to maintain identifier/client association. for example a database table that associates identifier 00112233445566778899aabbccddeeff with client/user #1337.
have the client resend the identifier sent to it at (1.) in all subsequent requests, be it in an HTTP Cookie request header, a ?sid=00112233445566778899aabbccddeeff param(*).
lookup the received identifier, using the mechanism at (2.), check if a valid authentication, and is authorized to do requested operation, and then proceed with the operation on behalf on the auth'd user.
Of course you can build upon existing infrastructure, you can use PHP's session management (that would take care of 1./2. and the authentication part of 4.) in your app, and require that client-side implementation do cookie management(that would take care of 3.), and then you do the rest of your app logic upon that.
(*) Each approach has cons and pros, for example, using a GET request param is easier to implement, but may have security implications, since GET requests are logged. You should use https for critical (all?) applications.
The session management is server responsibility. When session is created, a session token is generated and sent to the client (and stored in a cookie). After that, in the next requests between client and server, the client sends the token (usually) as an HTTP cookie. All session data is stored on the server, the client only stores the token. For example, to start a session in PHP you just need to:
session_start(); // Will create a cookie named PHPSESSID with the session token
After the session is created you can save data on it. For example, if you want to keep a user logged:
// If username and password match, you can just save the user id on the session
$_SESSION['userID'] = 123;
Now you are able to check whether a user is authenticated or not:
if ($_SESSION['userID'])
echo 'user is authenticated';
else
echo 'user isn't authenticated';
If you want, you can create a session only for an authenticated user:
if (verifyAccountInformation($user,$pass)){ // Check user credentials
// Will create a cookie named PHPSESSID with the session token
session_start();
$_SESSION['userID'] = 123;
}
There are numerous way for authentic users, both for Web applications and APIs. There are couple of standards, or you can write your own custom authorization / and or authentication. I would like to point out difference between authorization and authentication. First, application needs to authenticate user(or api client) that request is coming from. Once user has been authenticated, based on user's identity application needs to determine whatever authenticated user has permission to perform certain application (authorization). For the most of traditional web applications, there is no fine granularity in security model, so once the user is authenticated, it's in most cases also and authorized to perform certain action. However, this two concepts (authentication and authorization) should be as two different logical operations.
Further more, in classical web applications, after user has been authenticated and authorized
(mostly by looking up username/password pair in database), authorization and identity info is written in session storage. Session storage does not have to be server side, as most of the answers above suggest, it could also be stored in cookie on client side, encrypted in most cases. For an example, PHP CodeIgniter framework does this by default. There is number of mechanism for protecting session on client side, and I don't see this way of storing session data any less secure than storing sessionId, which is then looked up in session storage on server-side. Also, storing session client-side is quite convenient in distributed environment, because it eliminates need for designing solution (or using already existing one) for central session management on server side.
Further more, authenticating with simple user-password pair does not have to be in all case done trough custom code which looks up matching user-record in database. There is, for example basic authentication protocol , or digest authentication. On proprietary software like Windows platform, there are also ways of authenticating user trough, for an example,ActiveDirectory
Providing username/password pair is not only way to authenticate, if using HTTPS protocol, you can also consider authentication using digital certificates.
In specific use case, if designing web service, which uses SOAP as protocol, there is also WS-Security extension for SOAP protocol.
With all these said, I would say that answers to following question enter decision procedure for choice of authorization/authentication mechanism for WebApi:
1) What's the targeted audience, is it publicly available, or for registered(paying) members only?
2) Is it run or *NIX, or MS platform
3) What number of users is expected
4) How much sensitive data API deals with (stronger vs weaker authentication mechanisms)
5) Is there any SSO service that you could use
.. and many more.
Hope that this clears things bit, as there are many variables in equation.
If the API based APP is a Client, then the API must have option to retrieve/read the cookies from server response stream and store it. For automatic appending of cookies while preparing request object for same server/url. If it is not available, session id cannot be retrieved.
You are right, well the reason things are 'automatic' in a standard environment is because cookies are preferred over URL propagation to keep things pretty for the users. That said, the browser (client software) manages storing and sending the session cookie along with every request.
In the API world, simple systems often just have authentication credentials passed along with every request (at least in my line of work). Client authors are typically (again in my experience) reluctant to implement cookie storage, and transmission with every request and generally anything more than the bare minimum...
There are plenty of other authentication mechanisms out there for HTTP-based APIs, HTTP basic / digest to name a couple, and of course the ubiquitous o-auth which is designed specifically for these things if I'm not mistaken. No cookies are maintained, credentials are part of every exchange (fairly sure on that).
The other thing to consider is what you're going to do w/ the session on the server in an API. The session on a website provides storage for the current user, and typically stores small amounts of data to take load off the db from page to page. In an API context this is less of a need as things are more-or-less stateless, speaking generally of course; it really depends what the service is doing.
I would suggest you send some kind of token with each request.
Dependent on the server and service those can be a JSESSIONID parameter in your GET/POST request or something mature like SAML in SOAP over HTTP in your Web Service request.

Authentication in WCF

I am currently following this scenario
Instead of a Windows Forms client, I have an ASP.NET MVC web app.
I am a little worried about the sending of the username and the password
on every call to the Web Service.
That means I will have to carry this information all the time in the session.
Wouldn't that be little security problem ?
Why would you have to carry the credentials all the time in the session? According to the example you're following, they're being set in the proxy (when it's created).
If you're worried about having to cache the credentials for recreating the proxy as needed, then you can cache an instance of ChannelFactory, and then generate new proxies from that instance as needed.
Regardless of what path yout take, the credentials are going to have to be stored somewhere, somehow, unless your application prompts the user for their credentials for every WCF operation.
You can implement WS-Security in your service.
This means you can send user credentials in the header of the message encrypted. Lots of examples out there for this.

REST and authentication variants

I am currently working on a REST library for .net, and I would like to hear some opinions about an open point I have: REST and authentication.
Here is an example of an RESTful interface used with the library:
[RestRoot("/user")]
public interface IUserInterface
{
[RestPut("/")]
void Add(User user);
[RestGet("/")]
int[] List();
[RestGet("/get/{id}")]
User Get(int id);
[RestDelete("/delete/{id}")]
void Delete(int id);
}
The server code then just implements the interface and the clients can obtain the same interface through a factory. Or if the client is not using the library a standard HTTP request also works.
I know that there are the major ways of either using HTTP Basic Auth or sending a token to requests requiring authenticated users.
The first method (HTTP Basic Auth), has the following issues (partly web browser specific):
The password is transmitted with every request - even with SSL this has some kind of "bad feeling".
Since the password is transmitted with a request header, it would be easy for an local attacker to look at the transmitted headers to gain the password.
The password is available in the browsers memory.
No standard way to expire user "sessions".
Login with a browser interrupts the look and feel of a page.
The issues for the second method are more focused on implementation and library use:
Each request URI which needs authentication must have a parameter for the token, which is just very repetitive.
There is a lot more code to write if each method implementation needs to check if a token is valid.
The interface will become less specific e.g. [RestGet("/get/{id}")] vs. [RestGet("/get/{id}/{token}")].
Where to put the token: at the end of the URI? after the root? somewhere else?
My idea was to pass the token as parameter to the URL like http:/server/user/get/1234?token=token_id.
Another possibility would be to send the parameter as an HTTP header, but this would complicate usage with plain HTTP clients I guess.
The token would get passed back to the client as a custom HTTP header ("X-Session-Id") on each request.
This then could be completely abstracted from the interface, and any implementation needing authentication could just ask which user the token (if given) belongs to.
Do you think this would violate REST too much or do you have any better ideas?
I tend to believe that authentication details belong in the header, not the URI. If you rely on a token being placed on the URI, then every URI in your application will need to be encoded to include the token. It would also negatively impact caching. Resources with a token that is constantly changing will no longer be able to be cached. Resource related information belongs in the URI, not application related data such as credentials.
It seems you must be targeting web browsers as a client? If so you could investigate using HTTP Digest access authentication or issuing clients their own SSL certificates to uniquely identify and authenticate them. Also, I don't think that session cookies are necessarily a bad thing. Especially when having to deal with a browser. As long as you isolate the cookie handling code and make the rest of the application not rely on it you would be fine. The key is only store the user's identity in the session, nothing else. Do not abuse server side session state.
If you are targeting clients other than the browser then there are a number of approaches you can take. I've had luck with using Amazon's S3 Authentication mechanism.
This is all very subjective of course. Purity and following REST to the letter can sometimes be impractical. As long as you minimize and isolate such behavior, the core of your application can still be RESTful. I highly recommend RESTful Web Services as a great source of REST information and approaches.
I agree with workmad3, if session life time needs to be maintained you should create a session resource. Post on that resource with user credentials (either basic authentication or credentials in the body content) will return unique session id. Delete on /session/{id} will log out the user.
If you want to control the session expiry time. When creating new session (post on session resource) the server will set a cookie on the response (using standard set-cookie header).
The cookie will contain expiry time. The cookie string should be encrypted on the server, so only the server can open that cookie.
Every consequent request to the server will send the session cookie in the cookie header. (it will be done automatically for you if your client is a browser). The server needs to "renew" the cookie for every request, i.e. create new cookie with new expiry time (extend session's timeout).
Remember to clear the cookie when the user calls delete on the session resource.
If you want your application to be more secured you can store the client IP in the cookie itself, so when a request arrives the server can validate that it was sent from the "original" client. But remember that this solution can be problematic when proxies are involved, because the server might "see" all the requests as coming from the same client.
The rest authentication I've seen treats the sessions as a REST resource for creation, destruction etc. and then the session ID is passed to and fro. The ones I've seen tend to use the session cookie for this as it's the only way to secure it really. If you pass the session id in the URL, you don't have any way of really authenticating it came from the correct client.
Authentication is a tricky problem with REST though, as it requires some form of state to be kept outside the URL which infringes upon REST principles of the URL being all that is required to represent state.