ServiceStack cookie value not same session id in Redis cache - session

I have configured AuthFeature with CustomUserSession and use RedisCache as User Auth Repository. And then I use C# JSON service client to authenticate service, authen OK but session ID store in cache does not same as cookie value.
Cookie: ss-id => I0ZIuzLijch3IY9Tut0z
Cache: urn:iauthsession:brSXBQPjmIB6Srv6EPCv
Please help !
Update ...
Below code use JsonServiceClient: using (var client = new JsonServiceClient("https://api.futabus.vn/api"))
{
var lRes = client.Post("/auth/credentials", new
{
UserName = user.UserName,
Password = user.Password
});
}
BUT when i post direct to https://api.futabus.vn/api/auth/credentials then cookie value same as session id in response object and in cache.

This contains nowhere near enough info to identify the issue, you should at a minimum show the HTTP Headers and code used to make the request.
But the session key is derived from the sessionId if it's not using ss-id then you're likely authenticating with RememberMe=true in which case ServiceStack stores the User Session against the ss-pid Cookie instead. If it's not then double-check the HTTP Headers as the Cookie you think is being sent is likely not the one being sent.

I have 3 applications:
1. Main website: example.com
2. User website: id.example.com
3. API: api.example.com. All cookies restrict to the first (1) website (root domain)
All websites have been written with ServiceStack Framework 4.0.
When i call Authentication from the second (2) to api.example.com using JsonServiceClient then:
the cookies store in the first (1) and cookies i get as soon as call authentication are different.
I think cookies store in the first (1) have been encrypted.
The first (1) using Form Authentication with machine key settings in web.config
Anyone else have idea?

Related

Set a Cookie in flask Redirect to external URL

I want to redirect a user from my flask application to the client application with a header (encoded session object) that the browser can store as a cookie for further requests.
I'm authenticating a user using a different server and on a successful sign-in, he is redirected to my flask application where I set the user in the database and the session object. And, right after this is done, I need the request to be redirected to my client application. So, I use flask.redirect to redirect the user to my client application. Now, for the browser to store the user information, I want to send the session object to the browser as a cookie.
TLDR;
This is what I'm trying to do:
Client reaches content server.
Client does not have an active session, is redirected to authentication server with a callback to content server.
Content server creates session and redirects back to Client with session cookie.
Client reaches Content server.
Content server verifies session cookie and allows access to client.
Authentication is on a separate server, but the content server and client both need to keep track of the session via a cookie. The part I'm unable to do is make the Client (localhost:3000) keep track of the session.
The following is what I tried:
resp = flask.make_response()
resp.set_cookie('Set-Cookie', 'this is the session cookie I want the browser to set for further requests')
return flask.redirect('http://localhost:3000/', Response=resp)
This gives me the error:
File "/home/shaily/.virtualenvs/venv/lib/python3.6/site-packages/werkzeug/utils.py", line 507, in redirect
mimetype="text/html",
TypeError: __call__() got an unexpected keyword argument 'mimetype'
Is there an alternative or a way I can fix this?
"redirect functionality" can refactored in the following way.
resp = redirect("http://localhost:5001")
resp.set_cookie('a', 'x')
return resp
Referring a comment on this question, we can't pass 'Response' objects to redirect. Response has to be another Class
(useful when a wrapper class of werkzeug.Response) as written here.
According to how sessions are implemented in flask, on making any changes to the session object during the lifecycle of an http request, the encoded session object is sent as a cookie in the http response to this request. So, I no longer need to explicitly send it.
I was unable to read the cookie in my client application using document.cookie since by default, session cookies are httpOnly, i.e., they cannot be accessed via javascript applications, for security reasons. What httpOnly does let you do is let your browser store the cookie for further http requests to the server. If for some reason, you still want to read the session cookie in javascript, you cant set SESSION_COOKIE_HTTPONLY to False in your server config.
To send a cookie with an http response, this solution worked well for me: In Flask, set a cookie and then re-direct user

Is it asp.net Core Cookie Authentication without identity session stateless yes or no?

I have been looking a lot of tutorials and always they say that the asp.net Core cookie authentication the user stays authenticated on the server side in a Session object with a session Id. But in the CookieAuthenticationHandler.cs SignInAsync only save the sessionId when Options.SessionStore exists, if this is not the case I suppose that in each request is send all encrypted claims without the need to store all data in to Session object (like token authentication). So, Can someone clarify it to me please.
CookieAuthenticationHandler.cs source code;
var ticket = new AuthenticationTicket(signInContext.Principal, signInContext.Properties, signInContext.Scheme.Name);
if (Options.SessionStore != null)
{
if (_sessionKey != null)
{
await Options.SessionStore.RemoveAsync(_sessionKey);
}
_sessionKey = await Options.SessionStore.StoreAsync(ticket);
var principal = new ClaimsPrincipal(
new ClaimsIdentity(
new[] { new Claim(SessionIdClaim, _sessionKey, ClaimValueTypes.String, Options.ClaimsIssuer) },
Options.ClaimsIssuer));
ticket = new AuthenticationTicket(principal, null, Scheme.Name);
}
var cookieValue = Options.TicketDataFormat.Protect(ticket, GetTlsTokenBinding());
CookieAuthentication can work just fine without enabling Session.
All the claims are serialized into the cookie and deserialized into a ClaimsPrinicpal by the Authentication middleware on each request.
So if you mean stateless as in no session state needed, yes, the state is in the cookie, passed with each request.
No.
To prove this, create a new app. Register a new user. Delete your database and recreate it. When you return to your app you will be treated as though you are still authenticated.
If anything, the cookie is simply used as a cache that lives beyond the session. Like any cache, you must check if it’s stale, which means synchronizing state between client and server.
And, as Phil Karlton said, there are only two hard things in computer science: cache invalidation and naming things.
Achieving statelessness should be treated as a goal, but not a religious mandate.
By default, without Session installed, it is stateless.
A simple test to prove it:
return a cookie to your client via CookieAuthentication/SignIn
save the cookie value somewhere
then SignOut (the server returns a SetCookie to reset the value of the authentication cookie)
Send a request from the client reusing the value obtained in 1.
despite the SignOut phase you will still be authenticated! If by default you had a server side session mechanism in place, this cookie would have become invalid because the session would have been destroyed and the server wouldn't be able to match the cookie with the session.

What will be returned to identify user by server if username can be same?

I'm new to server developing,and there is a question:
when user logins,what will be returned by server to identify the user so that when user next logins they needn't to input username and password again,and what will be saved in server to record state of users,saved in memory or database.And will the solution will be different among mobile app and website?
I'm confused about this,anyone can teach me,thanks!
There exist many authentication mechanisms with different properties to authenticate a client to a server.
The easiest one is with Sessions and I suggest you to start with it. The basic idea is that when a user succesfully login, the server generates a big unique random number (usually with an expiration time) and send it back to the user. Both client and server store this value somewhere. Next time the user performs a request, it sends back the session id and in this way the server knows it is the user that previously logged in. This mechanism is supported in almost every language and you can handle it very easily.
Another interesting authentication mechanism is called JWT (Json Web Token). In this case the server generates a self-contained token that user uses for future requests. In this case the server doesn't have to store the token because the needed information is embedded in the token itself. You can find all the necessary information and resources here: https://jwt.io/ .
There are also other standards to perform authentication that are slightly more complicated. One of the most popular is OAuth (https://en.wikipedia.org/wiki/OAuth).
When user sends his username/password, generate a session token. Then, store that token at the client side (as a cookie if using a browser for example). On the server side, you can save it in presistent store (database) if you need to keep it for long time, or in memory (user session).
Afterwards, the user needs to send that token to identify himself instead of re-sending his username/password each time. The session token can be sent in several ways; through cookies, Authorization header, post body, etc.
Also, consider sending the session token through a secure connection (https) for security concern, and check for session expiry as well.
You have to use session storage.
An example, in common page :
<?php
session_start();
if(!isset($_SESSION)) {
//Redirection to login page
header('Location: loginPage.php');
} else {
//User is log
var_dump($_SESSION);
}
And in login page :
<?php
session_start();
//Your query for verifing is username and password matched
$isMatched = true;
if($isMatched) {
$_SESSION['userId'] = 45687; //Id of the user
//You can save what you want in this session
}
And on every page you can retrieve the data save with $_SESSION['theValueYouSet']

REST API Login approach

We are building system that required login information for all pages. the application is designed to be Restful application using codeigniter as Phil Sturgeon library. This library is using API Key only to authorize api calls via sending it with every request over HTTPS connection.
Even if it using 2 way authentication or only API Key. What i am searching for a while is the following scenario:
User request the application for the first time (ex: https://www.xyz.com) then it will be redirected to the login page to check credentials
User enter the usernam/password and sent it via POST over the https
Server check if the information is valid then:
API KEY should be provided by the server to the client as a resource identified by this username (Here is the question???!!!)
How to send the API Key to the client in a secure way?
1) Could i use session-cookies and restore the API KEY in a cookie then use this API KEY on every coming request (This is violent the Stateless of the Rest and i don't sure if it securely enough).
2) Actually i don't know other options :) it's your turn if you could help
If you could give an example it would be a great help as i found and read lots of articles
:)
Since the connection is HTTPS, anything you send over the wire is secure (theoretically and provided you aren't being mitm'd). Not sure if the whole API is served over HTTPS (you didn't specify), so even though you could return the key as part of the login (while still under the umbrella of HTTPS), if the rest of the api isn't HTTPS, the key could be sniffed on the next request.
Sessions and cookies aren't typically part of a RESTful application; REST is stateless.
Something like a revolving key would be better for non-HTTPS (would work with HTTPS too). You login via HTTPS, server returns the api key, you use it on the next request, server returns new api key, you use it on the next request and so on. While it's better than a single api key over non-HTTPS, it's not perfect. If someone sniffs the response from one of the subsequent requests and you don't end up consuming that key, they can use it. This shrinks the attack vector to a non-HTTPS response from server to client since if a request from client to server is sniffed, the api key will have already been consumed by your legitimate request. However, more should be done to secure the api if you aren't serving it over HTTPS.
If it were me, I'd look into request signing + https. There's some talk of request signing here: https://stackoverflow.com/a/8567909/183254
There's also some info on digest auth at the Securing the API section of http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/
A pseudo-code example js function on the client
function get_calendar(){
var key = $('#api_key').value();
$.ajax({
type: 'get',
url: '/index.php/api/calendar?key=' + key,
success: function(response){
// show calendar
// ...
// set received api key in hidden field with id api_key
$('#api_key').value(response.api_key)
}
})
}
Example controller method:
function calendar_get($api_key = ''){
if($api_key_matches){//verify incoming api key
$r = array();
$r['calendar'] = $this->some_model->get_calendar();
$r['api_key'] = $this->_generate_api_key();// generate or get api key
}
$this->response($r);
}

asp.net Web Api custom authentication requirement for mobile client

Please provide your feedback on my solution against following requirements.
Requirement (similar to):
1.a let say that authentication Token is made out of the Email and date and is encrypted
1.b authentication Token is send back to the client through header
1.c authentication Token is stored on client and server
My solution :
1) To send authentication Token back to the client through header. i have used cookie, and following code.
HttpCookie cookie = new HttpCookie("AuthenticationToken");
cookie.Value = "EncryptedToken";
Response.Cookies.Add(cookie);
2) I will store authentication Token in database, and for each request i compare token saved in cookie with token stored in database. (assume that encrypt,decrypt operations are done properly )
Your feedback/commments?
It looks to me OK. However, if you are encrypting (so you can decrypt back) and can find out email (identifying user) and time token issued (hence verify whether expired or not), do you still need to store it in database? I would, only if i had other requirements such tracking, etc.
I have no expert knowledge in security. To me your idea sounds doable.
However, I was curious why you wanted to do "custom" authentication like this?
Have you taken a look at "build it" ASP.NET authentication done in Web.API?
Then you could create a custom HttpOperationHandler using standard .net stuff like:
var ticket = FormsAuthentication.Decrypt(val);
var ident = new FormsIdentity(ticket);
...
var principle = new GenericPrincipal(identity, new string[0]);
Thread.CurrentPrincipal = principle;
...
if (!principal.Identity.IsAuthenticated)
return false;
Also, you might want to read about Thread.CurrentPrincipal and Current.User
The pro is that you don't need to store authentication token in some DB on the server and retrieve it on every request.

Resources