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

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.

Related

ServiceStack cookie value not same session id in Redis cache

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?

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']

Number of external requests when serving a resource

So, I have a web application that makes a lot of requests to the server for data. A project requirement is to have very fast server response times. The server is hosted on a cloud based platform.
The app uses sessions to keep track of user authentication once they've logged in. Since it's hosted on a cloud provider, I'm using a cache to back up session storage (in my case it's Auzre cache, but if you're unfamiliar with that think Redis)
The current flow is like this:
The user accesses a resource
Trying to get the session based on the session ID via the cache. This is a cache request.
User is authenticated via session state (if logged in).
Request for data is sent, usually via cache.
Data is returned to the user.
The problem with this approach is that it's hitting the cache twice. Removing the session altogether caused a significant speed improvement (about 50%).
I was considering hitting the cache once, asking for both the key I need for the user, and the SessionID to save the extra round trip. However, I've never seen this approach before, and it requires 'rolling my own session' as I'd have to generate the session IDs and such. I feel like there might be a simpler, easier way.
So, what would be the most efficient way to serve the user a resource and authenticate them?
Note: I'm using ASP.NET MVC/ WebAPI with C# but I don't find that very relevant to the question, so I left the language and platform out of the question because of it.
You would want to combine the authenticate and resource request steps into one single request. Not only is this faster, it is also safer than your implementation. Consider the following scenario:
User authenticate to the server. Result is success.
Authentication is changed. (e.g. user changes password, admin decides to lock the user account, etc.)
User makes a request using the sessionID in step 1.
To ensure that the user is not granted access to the resource, you'd want to authenticate the user precisely at step 3. But that doesn't make sense, you've already authenticated this user previously in step 1...
HTTP, in is core, is designed exactly to do this. There are various ways to pass authentication information along with the request, such as:
Write the authentication information in the content (stupid, but works)
Include authentication in the url, e.g. example.com/pic/123?sessionID=abc (better, but makes your url ugly and long)
Store session info in cookie (better, but what if the client does not support cookie? what about cookie expiration?)
Authenticate HTTP header (my best personal recommendation)
HTTP itself has an authenticate header meant to be compatible with "basic authentication" (it is well defined, look it up if you're interested). But you can implement your own custom header.
Any cache lookup is bound to be slow (compared to computation), so you should omit the cache for the authentication part all together. Your server should be stateless; i.e. do not keep track of login sessions. How do you know if the sessionID is valid? Put a timestamp on it. And to avoid others faking the sessionID, sign it as well.
So, your HTTP request would look something like this (pseudo code):
var request = new HttpRequest();
request.url = "example.com/pic/123";
request.Headers["CustomAuth"] = "id=abc&t=123456789&s=01de45890a";
Implement your own signing method, sort of like a hash function (you can use HMAC), and keep the key securely on the server. If the signature matches, you know you've signed this previously at the login, and it has to be from your server. A timestamp helps you detect session expiration and also protect against replay attacks.
Now in your server, do something like this:
public void Get(){
var authHeader = Request.Headers["CustomAuth"];
if(!validate(authHeader)){
Response.StatusCode = 404;
Response.End();
}else{
//something else
}
}
If you need to do login + session authenticate + resource request in one request, then there're simply just 2 ways for authentication. Users can either provide a username/password combination, or a session key. Think about this scenario, which comes from an API I worked on:
user register with username/password combo
server responds registration success / failure (e.g. username already taken)
if it was a success, user now logins with username/password combo
server returns a session token
Wouldn't it be simpler (and faster) if we do it this way:
user register with username/password combo
if it is success, respond "reg success" and "sessionToken=xxxxxx". if it is failure, respond "reg failure".
I hope this give you some idea.
Also, you can remove the authentication at the server end by modifying / restricting settings on the server to cater to requests coming only from the ip(s) where your web app is hosted. Your web application will let the request pass to server only if its authenticated and hence all the requests reaching the data server will be served automatically without checking for any authentication. In this case you will just need one cache hit to check if the user is authenticated and straight away hit the server.

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.

Can i regenerate my own session id in servlet? [duplicate]

Whenever you authenticate, your application should change the session identifier it uses. This helps to prevent someone from setting up a session, copying the session identifier, and then tricking a user into using the session. Because the attacker already knows the session identifier, they can use it to access the session after the user logs in, giving them full access. This attack has been called "session fixation" among other things. How can i change the session id once the user login to the system ?
You're still on the server while you invalidate the session.
//get stuff out of session you want before invalidating it.
currentSession = request.getSession(true);
UserProfile userProfile = (UserProfile) currentSession.getAttribute("userProfile");
//now invalidate it
currentSession.invalidate();
//get new session and stuff the data back in
HttpSession newSession = request.getSession(true);
newSession.setAttribute("userProfile", userProfile);
Get the existing; invalidate it; create a new one ...
1) Get the current Session with HttpServletRequest.getSession();
2) Clear the Session: HttpSession.invalidate();
3) Create a new one: HttpServletRequest.getSession(true);
Talking generally (because this isn't a Java problem at all, it's a general web problem) session fixation arises when session IDs are easy to discover or guess. The main method of attack is when the session ID is in the URL of a page, for example http://example.com/index?sessionId=123. An attacker could setup capture a session and then embed the link in their page, tricking a user into visiting it and becoming part of their session. Then when the user authenticates the session is authenticated. The mitigation for this is to not use URL based session IDs, but instead use cookies
Some web applications will use a cookie session based but set it from the initial URL, for example visiting http://example.com/index?sessionId=123 would see the session id in the url and then create a session cookie from it, setting the id in the session cookie to 123. The mitigation for this is to generate random session ids on the server without using any user input as a seed into the generator.
There's also browser based exploits where a poorly coded browser will accept cookie creation for domains which are not the originating domain, but there's not much you can do about that. And Cross Site Scripting attacks where you can send a script command into the attacked site to set the session cookie, which can be mitigated by setting the session cookie to be HTTP_ONLY (although Safari does not honour this flag)
For Java the general recommendation is
session.invalidate();
session=request.getSession(true);
However at one point on JBoss this didn't work - so you need to check this works as expected within your chosen framework.
Invalidate the current session and the get a new session:
//invalidate the current session
request.getSession().invalidate();
/*
get another session and get the ID (getSession()) will create a session if one does not exist
*/
request.getSession().getId();

Resources