Tomcat Unique SessionId - java

Is there any way to configure(xml) tomcat (6.x) to generate unique SessionId.
(Without extending ManagerBase/StandardManager).

I am capturing user login details in db table,with Session Id in a column with unique constraint,and am getting unique constraint exception
You should not store the Tomcat-generated session ID as an unique constraint in the DB. This makes no sense. Tomcat's session ID is only unique within all existing active sessions. The Servlet spec does not forbid to reuse the ID of an expired session for a new session at some point, months or years later. With a fixed length 32-char hexadecimal string as session ID, all possible IDs are not "unlimited". You can't prevent it from being reused for a different client at some point.
I do not understand why you would ever store a Tomcat-generated session ID in the DB lifetime long. You should remove it from the DB whenever it has expired. Or you should solve your problem differently. As you didn't state anything about the functional requirement behind this "solution", I cannot give a more suited answer. Here are however some hints:
Do it the other way round: insert or select the necessary data in/from DB, get the DB-generated ID and store it as an attribute of the HttpSession. For example the logged-in user ID, or just the whole User object.
Or, if it needs to expand the default lifetime of a session, e.g. "Remember me" option, then you should generate an UUID yourself (and test if it doesn't exist in DB yet) and use it in a separate cookie instead.

I'm working on this issue myself, and I'd like to mention that it is possible to generate a guaranteed unique ID using 128 bits (32 hexadecimal digits) using UUID. It is based on UTC time, and is guaranteed to be unique as long as the usec timestamps at which different UUID are generated are different.
See also RFC4122: https://www.ietf.org/rfc/rfc4122.txt
Java has a standard class for generating these IDs:
http://docs.oracle.com/javase/6/docs/api/java/util/UUID.htm

Just use a compound primary key, as CONSTRAINT PRIMARY KEY ("SID" , datum);

Related

How to store UUIDs client side

For my app I have a server-side database in which I store users and their data. I am wondering how to keep track of which user has which UUID. I want to make sure that only the same user with their own unique UUID can access their data in the database.
What would be the best way to do this?
In your database, create a table where each row represents one particular user. That table would have their permanently assigned UUID, along with name, email, etc.
Some databases such as Postgres and H2 support UUID as a built-in data type. Some databases proved a feature, perhaps as a plug-in, to generate a UUID value. For example, the uuid-ossp plug-in for Postgres. If not, you can generate a UUID in Java.
When creating an account for a user, create a row in that table. When a user logs in, look up their credentials in this table, retrieving their previously assigned UUID.
During the execution of your app, keep that retrieved UUID in memory as a java.util.UUID object. In a web app built on Jakarta Servlet, a good place to keep their UUID would be as an attribute on the Session. See Binding Attributes into a Session in the spec. See HttpSession#setAttribute and getAttribute.
When you write rows in other tables that belong to a particular user, include a column for their UUID. Include their UUID as a criteria in your queries.
You might want to look into multitenancy as a topic.
After authenticating the user (via your favorite authentication process), add a set-cookie response header with the user id (or any other data you deem appropriate) as the value.
Don't forget to set the cookie properties httponly, secure, and samesite.

How to update a database record using hibernate with no primary key

I am trying to create a web service using Jersey and connect to the database using Hibernate.
Due to security reasons, I don't want to pass the primary key value from the server to the client or the opposite direction. In that case, how can I update a record? From examples I've seen you should call session.load(key) and change the returned object, but like I said, I won't be having the key value.
You may not pass a primary key to update a record but it implies two things :
You must have another way to identify in a unique way a record (maybe a business key or a composite key).
it may cost in performance since your PK is automatically indexed, not the other fields. Creating multiple indexes may be a cost.

JavaEE application create a unique key using java.util.UUID

I want to make a javaEE application when users can register and confirm their email when receiving a email with a link after inserting their data in registration form (name, mail...)
To do that I am going to generate a long and unique key with java.util.UUID, store in a database and then send an email to the user with that key being part of the URL (Example: www.mysite.com/account.xhtml?id=KEY). Then the user will click the link, I extract the key from the URL and check if that key is stored in the DB. If it is, the user registration will be completed.
My question is, when creating that key with java.util.UUID, how can I know that it is a unique key? Should I check if there is another equal key in the DB and if so create a new one until the created key is unique?
What's the chance that a randomly-generated 128-bit integer will be equal to another randomly-generated integer?
If you just need peace of mind, use a primary key and if the insert fails due to a key collision, re-create a new UUID and retry the insert.
There are couple of ways you can do UUID in Java.
Java 5 onwards better practice is using java.util.UUID It is size of the string 36 characters. This link gives you simple example.
This discussion will give you answer to your question. It is very strong. I have never came across someone is complaining about its uniqueness.
But if you adding into DB or using in storage or using through network, size may be matters. So converting to other formats - Bases is good solution (Base64, Base85 etc). Please check this discussion here. You can use apache library org.apache.commons.codec.binary.Base64. Base85 is not safe for URLs.
My recommendation is, if you have may application/session beans/web services (many interconnections other applications and data transfers etc) are creating UUIDs, I prefer to do unique application name padding too. Like APP1, APP2 etc and then decode to other bases. If UUID is 6fcb514b-b878-4c9d-95b7-8dc3a7ce6fd8, then APP1-6fcb514b-b878-4c9d-95b7-8dc3a7ce6fd8 like that...
Though it is off the topic here, BUT When you use a URL like this www.mysite.com/account.xhtml?id=KEY, beware about SQL injection hacking attacks.

Creating empty objects in db or saving them later

I have the following table in my db:
CREATE TABLE document (
id INT PRIMARY KEY AUTOINCREMENT,
productModelId INT NOT NULL,
comment VARCHAR(50),
CONSTRAINT FK_product_model FOREIGN KEY (productModelId) REFERENCES product_model(id),
)
Of course, real table is much more complicated, but this is enough to understand the problem.
Our users want to see the number of the document when they click button "new". So, in order to do that, we have to create object in db and send to client that object. But, there is a problem. We need to know productModelId before we save the object in db. Otherwise we will have an sql exception.
I see two possible variants (both are ugly, really):
To show modal list with product models to user and after that create object in database with productModelId chosen by user.
To create a temporary number and after that to save the object in db when user finishes editing the document and saves id. We also need to remove NOT NULL case and validate this somwhere in code.
The first way is bad because we have too much modals in our application. Our UI is too heavy with them.
The second variant is ugly because our database is not consistent without all the checks.
What can you suggest we do? Any new solutions? What do you do in your apps? May be some UI tips. We are using the first variant at the moment.
Theory says that the id you use on your database should not be a relevant information, so the user should not see it if not well hidden in an URL or similar, so you should not display it to the user, and the problem you have is one possible confirmation of this theory.
Right now the solution you have is partially correct: it satisfies technical requirements, but is still bad because if the user doesn't complete the insert you'll end up with the DB having empty records (meaning, with ID and foreign key ok, but all other fields empty or with useless default values), so you are basically circumventing the database validations.
There are two better solutions, but both require you to review your database.
The first is not to use the id as something to display to the user. Use another column, with another "id", declare it unique on the database, generate it at application, display it to the user, and then use this other "id" (if it's unique, it is effectively an id) wherever needed.
The second one is the one that is being used often cause it does not require a central database or other authority to check uniqueness of ids, so scales better in distributed environments.
Drop the use of the common "id int" auto-incremented or not, and use UUIDs. Your id will be a varchar or a binary, an UUID implementation (like java.util.UUID, but you can find in other languages) will generate a unique id by itself whenever (and wherever, even on the client for example) you need it, and then you supply this id when saving.
We make it the following way.
Created table id_requests with fields issue_type_id and lastId. We need this in order to avoid the situation when two users hit the button 'new' and get the same ids.
And of course we added field innerNum to all the tables we use this feature in.
Thank you!

Generate Unique Id for client server authentication

I'm creating an app where in, a client sends a request to the server and in turn gets a unique request id. This unique request id would be used later authenticate the client when it wants to interact again with the server.
The request of client are of two types:
New request, where it has no existing id and the response from the
server generates and returns an id.
Existing request with the id. The server then processes the clients
request for the id supplied.
My problem is how do I generate the id? I'm using Java and MySQL server database. If I use an auto-incremented database generated id, then it becomes too easy for the client to guess the ids. Another client could maliciously generate a few ids by guessing and misuse them (There is no authentication between the client/sever, except for the ids :< )
If I generate a random id using UUID or some other randomize algorithm, then I need to check the entire database (which could have thousands of records), to really check and guarantee if the random id is unique indeed? Or would it be fast inside the database to check if the id exits and won't cause performance issues?
What measures should I take? Do I need to have more security measures for authentication between the client and the server, other than the unique id?
Using java.util.UUID.randomUUID(); you can generate a cryptographically secure, random UUID.
Since the UUID is 128 bit long, the chance for a collision is negligible, but if you really want to check for collisions, you can do that by storing active UUIDs in the database and check for duplicates after generation.
You can use Java's UUID.
Something like :
UUID uniqueKey = UUID.randomUUID();
And if you don't wanna use that, you can use the time, as it is always changing, add a random number if u wanna be sure.
Create an encoded and unique key for each session, that will be created using the unique data you have of that user, something like his email, current time, etc.
String yourString = "user#email.com"+"timestamp";
byte[] bytesOfMessage = yourString.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);
Would generate a unique id for each request, store them in a table in your database that contains an expiry timestamp, userid and the key. The on each request, renew the "expiry" time if its still valid, or return error if its expired or invalid.
The valid keys table I use is something like:
userId(int)
key(varchar(32))
expiry(int)
Then if you wanted to see if a user has a valid session open you'd just check that table for the userId and make sure that it's a unique column, to avoid storing a historic of previous sessions.
If you use Spring Framework you may found useful another UUID implementation org.springframework.util.AlternativeJdkIdGenerator:
IdGenerator generator = new AlternativeJdkIdGenerator();
UUID uuid = generator.generateId();
Which is from the documentation:
An {#link IdGenerator} that uses {#link SecureRandom} for the initial
seed and * {#link Random} thereafter, instead of calling {#link
UUID#randomUUID()} every * time as {#link
org.springframework.util.JdkIdGenerator JdkIdGenerator} does. * This
provides a better balance between securely random ids and performance.
If you 'd like to generate it on MySQL side, I think this will do just fine
md5(concat(UNIX_TIMESTAMP(),<user_id>))
If the field is indexed, query won't take long.
Use a UUID to generate a base ID that is nearly always unique.
Hash the base ID to make it difficult for clients to guess and spoof.
Store the hashed ID in the database using a column with a unique constraint.
On the rare occasion the unique constraint is violated, repeat the above steps.

Categories