I'm a little confused about the cookie and I want to know can we use cookies somewhere other than the browser, like a mobile app or desktop app. Is the cookie dependent on the browser?
No, cookie is not dependent on browser.
Cookie is dependent on HTTP "User-Agent" -- the software/library client that is acting on behalf of a user, following HTTP protocol. Browser is just one type of it. Other types of "User-Agent" includes:
CLI software that can send HTTP request, such as curl or wget.
Library that can be imported in project and send HTTP request. Take Node.js project for example, they can be request or axios. All major programming language have its own HTTP client libraries.
Self-implemented HTTP client logic code.
more...
In a mobile app or desktop app, if HTTP is used for application, it is highly likely that cookie is used.
Any HTTP client can use cookies. A cookie is just a HTTP header sent by the server, with a value that is sent back to the server by the client in subsequent requests. Consult the documentation of your HTTP client to see if there is built-in support for remembering cookies.
Session Based Authentication
In the session based authentication, the server will create a session for the user after the user logs in. The session id is then stored on a cookie on the user’s browser. While the user stays logged in, the cookie would be sent along with every subsequent request. The server can then compare the session id stored on the cookie against the session information stored in the memory to verify user’s identity and sends response with the corresponding state!
Token Based Authentication
Many web applications use JSON Web Token (JWT) instead of sessions for authentication. In the token based application, the server creates JWT with a secret and sends the JWT to the client. The client stores the JWT (usually in local storage) and includes JWT in the header with every request. The server would then validate the JWT with every request from the client and sends response.
The biggest difference here is that the user’s state is not stored on the server, as the state is stored inside the token on the client side instead. Most of the modern web applications use JWT for authentication for reasons including scalability and mobile device authentication.
Scalability
Session based authentication: Because the sessions are stored in the server’s memory, scaling becomes an issue when there is a huge number of users using the system at once.
Token based authentication: There is no issue with scaling because token is stored on the client side.
Multiple Device
Session based authentication: Cookies normally work on a single domain or subdomains and they are normally disabled by browser if they work cross-domain (3rd party cookies). It poses issues when APIs are served from a different domain to mobile and web devices.
Token based authentication: There is no issue with cookies as the JWT is included in the request header.
Token Based Authentication: using JWT is the more recommended method in modern web apps. One drawback with JWT is that the size of JWT is much bigger comparing with the session id stored in cookie because JWT contains more user information. Care must be taken to ensure only the necessary information is included in JWT and sensitive information should be omitted to prevent XSS security attacks.
Related
If a user authenticates via OpenID Connect on a client and triggers a long-running server-side request, how can the server keep the access token valid if the operation takes longer than the access token's expiration time?
We have an application suite consisting of several server-side backend applications (typically accessed via REST, HTTP, and/or WebDAV), several web frontend applications and several client-side (i.e. desktop) applications. We already support the Basic and Kerberos/Negotiate authentication schemes and are currently adding support for OpenID Connect.
Our backend applications are typically accessed by the web frontend and client applications, other server-side backend applications, and 3rd party customer applications when our software is integrated into their system. We currently pass OpenID access tokens via the Bearer scheme to the backend applications.
In a typical scenario, a user (authenticated on a local client or in a web frontend) triggers a server-side operation which may possibly run for several minutes, hours, days, or even weeks. This operation accesses other backends on the user's behalf, e.g. a Web-DAV based server-side file system, to access additional data. All backend applications need the user's authentication information to grant access and access further user details for authorisation (e.g. to only grant access to the user's own files).
Obviously, this means that the access token provided with the original backend call may expire before the operation is completed. The server therefore needs a way to refresh the access token without user interaction. Our code can already do this if it knows the user's refresh token (using the refresh token and the application's client ID and secret to access the OIDC Token endpoint).
But how can we "correctly" pass the refresh token to the server?
The client has (potentially) the full set of ID, access, and refresh tokens. But from what I understand, the Bearer scheme expects that the passed token is the access token. Compatibility is important here, since our backend applications may also be accessed by 3rd party client applications. Assuming that getting the refresh token into the server application is the correct approach at all, we therefore still have to support situations where the caller can only provide an access token (with the obvious implications that in these cases, long-running operations will not be able to access other backend services on the user's behalf).
I could imagine the server accepting either an access token or a refresh token via Bearer. But from what I understand, the only "argument" a client may pass with a correct Bearer authentication header is a single Base64 encoded string, i.e. the (access) token. The client could pass an access or refresh token here, but I don't see how the server could then tell which it is, as to my knowledge both token types are opaque.
I understand that the original idea is for server operations to be short lived, so that keeping the access token up to date is the client's responsibility. But surely we cannot be the first who do need to combine OIDC with long-running server-side operations. Is there an accepted way to pass a refresh token to a server, or, alternatively, a completely different approach that I'm missing?
I would like to know if the following design for token-based authentication is sound.
Client posts login credential
After validating, server generates (session_key, expires_at) <- (a 256-bit pseudo-random string, some date in the future) and save it in the storage system of choice.
Server sets the session_key in the HTTP-Only cookie in the response.
Server sets the response payload {session_key: ..., expires_at: ...}. The reason is that non-browser clients do not have cookie and they will read this payload, locally store it for the future use.
Concretely, I think the system needs to send the token in the payload as well as a cookie for non-browser clients. Is this a common practice? Or am I missing something important, and there are better alternatives?
As I pointed out in another question, this is fine. It doesn't expose the session key any more than if it is only in a cookie. This could only happen if the attacker can call your authentication endpoint with a valid user/password combo.
Make sure your authentication endpoint does not accept valid sessions and echo back their key as that could expose you to CSRF and session stealing!
For alternative authentication methods, check out the Web Authentication Guide, I put together.
Like the Facebook application, you only enter your credentials when you open the application for the first time. After that, you're automatically signed in every time you open the app. How does one accomplish this?
There's a commom line in all auto-login implementations
Upon an initial login, a token is received and stored on the client side
Upon subsequent visits, if token is available on the client side, the server resolves the identity and logs in automatically
Now concrete implementation variations can be numerous. The token can be a session ID (encripted or not), OAuth token, custom token, username and password should be avoided. Storing token can be on within a browser cookie, browser local storage, can have a server counter-part. Security is the major concern. Generally about the topic you can read more here https://softwareengineering.stackexchange.com/questions/200511/how-to-securely-implement-auto-login
You have an interesting explanation of how does Stackoverflow do it https://meta.stackexchange.com/questions/64260/how-does-sos-new-auto-login-feature-work.
I'm tasked with creating a service-oriented ecosystem for a client. The whole thing is going to be REST based and built in ASP.NET, but my question is technology-agnostic. We want to have a centralized authentication service that issues JWT tokens and claims that are trusted by the other services in the environment.
My issue is this - what's the first thing that a web client (browser) requests? All of the diagrams I've seen (I'll try to add a couple of example links) make it seems as if the client needs to be self-aware and realize that they're going to need a token before they make the first request to the functional REST service, which seems, well, janky to me.
The way I want it to work is that they just attempt to access the secured resource, but there's no auth token with the request my REST service challenge them for user/password, but then delegate the authentication to my auth service. So:
Browser requests restricted resource on REST service
REST service returns 401
Browser gathers credentials, sends to same web service
REST service connects to the authentication service, passing along the Auth header from the client's request
Auth service creates the JWT token and returns it to the REST service
REST service validates the JWT and replaces the Auth header with the JWT token
JWT token is persisted for subsequent requests, up to expy setting
...am I completely off about this? Does the web client need to know that there's a separate auth service involved and make one request there to get their JWT, and then a second request for the REST resource passing the JWT? That seems clunky to me, I hope that's not the idea.
Also, another n00b question - is the JWT token automagically kept by the web clients and re-sent with every request so I don't have to go through the auth service step each time? Is that what the expiration setting is for?
TIA.
See figure 1 here for an example of what I mean: http://msdn.microsoft.com/en-us/library/hh446531.aspx
Starting with your last question will make the rest of the answers clearer:
"...is the JWT token automagically kept by the web clients and re-sent with every request.." - The idea is to issue JWT once, send it to the client so client can save it and send it on each subsequent request. This way your front-end app will send username and password just once and then use JWT for authentication. You will have to store the JWT using browser storage (local or session) or cookies (common fallback for older browsers).
"...Does the web client need to know that there's a separate auth service involved..." - You will need to send the username and password to a service in order to have the JWT issued. You could implement it with just one request, but you need to send credentials to the service (provided by the user), receive JWT as part of response and store it (as above). It might be easier to do it on a separate request, depending on requirements and implementation.
I am developing an API as a middleman between a Windows app and the database. The webserver will just be an ASP. NET generic handler returning json.
Users will log into the app and their credentials will be transmitted over the wire. From there what I was going to do was generate a session key that the app could use from then on with every request.
This will not be an open API in the foreseeable future.
Now what I am wondering is if this is secure enough? How can I stop people from using fiddler to just replicate the calls?
Is there a better approach to this? Would it help if I used SSL?
I don't want to complicate matters by using oauth.
Thanks!
Use SSL. In order to obtain the session token the client should authenticate himself with a username and password transmitted over SSL. Once authenticated the token should be transmitted to the server over SSL to prevent from man-in-the-middle attacks.
So here's the flow:
The client sends his credentials (username and password) over SSL to a web method
The web method verifies the credentials and generates a session token and returns this session token to the client.
The client sends the session token on subsequent requests to protected resources.
The server verifies the token and if valid grants access to the protected resource.
You use simple Forms Authentication to generate the session tokens. The FormsAuthentication.Encrypt and FormsAuthentication.Decrypt methods could be a good start for you. The forms authentication token contains an encrypted value of the currently authenticated user. If you are running in a web-farm make sure that you have static machine keys on all nodes of your web farm, otherwise a session token encrypted on one node might not be decrypted on another node.
As an alternative to session tokens you could use basic authentication over SSL. The drawback is that credentials are sent over the wire on each request. Even if you are using SSL, the password is still transmitted over the wire, so this method is less secure than session tokens but easier to setup.