Is it secure to authenticate a user using the JSessionId that the client passes to the server ?
Assume that in a Spring app, we store the jsession id for a user that provided correct credentials while logging in, in a database and we authenticate each subsequent request based on that jsession id.
Does this method provide the same security level of using Java Web Tokens ?
JWT tokens are cryptographically signed so they are much more difficult to forge compared to session IDs.
Session IDs are generated using a secure random number generator which may be predicable depending on the implementation.
https://news.netcraft.com/archives/2003/01/01/security_advisory_2001011_predictable_session_ids.html
Some more information on why JWT is preferable over session IDs may be found here:
https://stormpath.com/blog/beginners-guide-jwts-in-java
Related
If BASIC authentication was not build to handle logging out, what alternate authentication methods exist for authenticating backend services that need to be able to log out?
I found these references stating that BASIC auth is not able to do log
out without some hackiness:
How to log out user from web site using BASIC authentication?
How do I log out?
We are using BASIC authentication to log into backend applications, and FORM authentication for frontend applications. After our team tested the stack on FireFox/IE, it was found that a user would not be able to log out if they logged into the backend services via BASIC authentication on those browsers. The hacks and workarounds are unacceptable to my team (asking user to enter incorrect credentials, making user close browser, use javascript to send incorrect credentials, ask user to clear browser cache, etc), so we are seeking advice on alternative authentication methods that DO allow logging out
EDIT- My temporary workaround for logout:
I am currently getting around this problem by using FORM authentication. One problem is that my backend services rely on the shared frontend login.html form, and another problem is that Postman does not support logging in via a redirected FORM input, and our client Arquillian calls blow up from the login form.
FORM authentication gets rid of the "I can't log out with BASIC" problem, but now I can't authenticate as straightforwardly.
Form based-authentication
If it's okay to keep the session state on the server, you can go for form-based authentication.
Send the credentials in the form, if the credentials are valid, the server will issue a cookie that will be sent back and forth to identify the session on the server. To logout, the session can be invalidated:
session.invalidate();
You also can configure your application to expire the sessions due to timeout:
<session-config>
<session-timeout>60</session-timeout> <!-- minutes -->
</session-config>
Token-based authentication
If you want a stateless mechanism, go for token-based authentication.
The client exchanges hard credentials (such as username and password) for a piece of data called token. For each request, instead of sending the hard credentials, the client will send the token to the server to perform authentication and then authorization.
For the token, you could use JSON Web Token (JWT). It's an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.
JWT is a generic name for the following types of token:
JSON Web Signature (JWS): The payload is encoded and signed so the integrity of the claims can be verified.
JSON Web Encryption (JWE): They payload is encrypted so the claims are hidden from other parties.
The image was extracted from this page.
The token can define an expiration date in the exp claim. For logout, you can remove the token from the client.
You also could keep the track of the tokens in a whitelist on server-side and invalidate them as you need. There's no need to store the whole token on server side though: Store only a token identifier in the whitelist and use the jti claim to store the token identifier in the token.
I suggest you to have a look at Apache Shiro, especially the way session are managed (https://shiro.apache.org/session-management.html).
They have namely abstracted the concept of session so that it can work in various situations: in a webapp (in such case, it's simply a wrapper around the HTTP session), in a standalone app, etc...
In your particular case, the front-end could open and close (logout from) a Shiro session that is shared with the backend layer.
See the sentence:
Heterogeneous Client Access
(...)
For example, a (desktop) application could ‘see’ and ‘share’ the same physical session. We are unaware of any framework other than Shiro that can support this
I'm writing a mobile app that communicates to a remote Java service via REST. I have protected my (SpringBoot) web service with https protection (due to the nature of the data, it needs to be secure) but my question is about which user/password I use to secure the https calls.
Should the username and password I use in the https header be a service account that the client (mobile app) and Java service knows or should it be the public user's username and password? The easiest option is just to use a service account but this means the mobile app will have those details built into it and distributed publically (albeit in compiled form).
Going the other way and using the user's username and password means I'll have to have the logon REST endpoint open and unsecure (which is fine I guess), but it just makes it slightly more fiddly.
Good question, and I would reckon you to use token based authentication and authorization scheme. Firstly you should have a login page where client logs in by providing username and password which is authenticated by calling some remote login service which maintains it's own user store or may use an existing one in your organization if any. Upon a successful authentication, the auth service should provide the client with a valid token, which then be refreshed time to time. The mobile or web client should pass in the token to the downstream microservices when a request is sent and this token should be sent inside the Authorization HTTP header.
Exposing the username and password while passing it around the network normally not considered as a good solution and that's where token becomes handy too. Token is the normal procedure that people use to secure rest endpoints. Yous rest endpoint should intercept each and every request comes at it, passes the token to the auth provider and verifies that. If the token is valid it will allow the request otherwise it should deny it.
Security is a pretty much larger topic and you have X.509 certificates other than tokens to encrypt the data sent across the wire over https and so forth. I suggest you to take a look at the spring security documentation since that will be a good starting point. Spring Security gives lots of hooks for developers which can be used out of the box with some sensible defaults. You can use JWT style tokens, Oauth tokens and spring security supports all these different forms too.
I have a requirement for a REST API that has token-based authentication: we will have replicated application servers with a load balancer, since tokens are generated by one server when a user is authenticated, and different requests from the same client can be handled by different servers, is there a generic technique or technology to share those tokens between the different servers?
About technologies, we will be using the Java stack, more specifically Grails.
About the application servers, we might have more than one database. This comment is important because discussing with colleagues, someone suggested to manage the token sharing using the same database from all application servers. I'm looking for a solution that doesn't need a centralized database, that let us scale on the DB side.
When using token based authentication, there's a server that authenticates the user and issues a security token. Authenticating the user can be done in many ways (verifying username/password against a database, verifying a certificate on a smart card etc).
Once the token is issued and signed by the authentication server, no database communication is required to verify the token. Any service that accepts the token will just validate the digital signature of the token.
The client (caller of your service) is responsible to send the token along with the request. So no matter which server behind your load-balancers handles the incoming request, it only needs the public key associated with the signing key to verify whether the request is valid.
Which security protocol to chose depends on the requirements you have. OAuth is used often for internet applications. WS-Federation and SAML-P are used a lot in enterprise environments.
As far as I see JWT (JSON Web Token) is supported in grails - it seems that this is what you're looking for. Basically you need to separate the authentication server as in this image. Authentication verifies the user/pass being sent and issues a token that is easily parseable without any further access to DB. To only thing that needs to be shared is the key that will be used to decode the incoming JWT. See, how it works.
I would like to know what is the best practice on how to work with authorized RESTful server.
Say that after login the server provides me a token, and then for each request I will have to provide it as well. My question is: should I save this token in my server's session? or should I do authentication against the data base for each request?
There are several ways. You could only keep it in memory, but then if you have multiple servers in a cluster, you'll have to make sure a request for a given token always goes to the same server, or to distribute the token among all the servers.
You could also cryptographically sign the token data, include the data and the signature in the token, and verify the signature at each request. That way you can be certain that the token has been issued by you, and you can be completely stateless.
Note that, if you're using HTTP sessions already, the token is redundant, since the session mechanism already uses a token in a cookie to track sessions.
Use a session cookie to track an authenticated session instead of hitting the database each time.
I finalize my OAuth 1.0a provider based on Jersey but I'm facing a small issue I don't know how to deal with
During the OAuth dance, the user has to authenticate with his credentials (login/password)
With my implementation, for the moment, he has to authenticate every time
During the authorization step, the only token which is sent to the web service is the request token related to the consumer
Jersey doesn't manage session
How can I avoid to ask authentication if the user is already authenticate?
Thanks
The client application which uses your oAuth provider should maintain state in the session. As a minimum it has to keep the access token as that will be needed to access the user's data. The presence of a valid access token could be used as an indicator that the user is authenticated.
it seems that when the user first authenticates to the web service, the web service should provide a login cookie which is validated each time the user wants to authorize a new client
could you assess this method?
now I need to find how handle cookie with jersey...