20 November 2014

When implementing Spring Security in JSF application, many problems happens, and one of the most important one is the redirection in case of HTTP errors!

In this post, I'll take about 2 points, the first point is how to implement the Login page (you will find many resources illustrate this - for example this) but I'll extend it allowing the user to continue on the page he was coming from (aka. Saved Request URL), the second point and the more important one is handling HTTP errors in case of Ajax requests.

Point #1 Handle Login From:

Initially, you have your JSF application (in my case I use Primefaces, but shouldn't matter at all, because the solution is JSF related not primefaces-related)

Very simple!, regularly with spring security, we submit the form to /j_spring_security_check but we have different situation here, we have a command button which send POST request to the same URL of the page.

2 solutions here, I'll take about one of them (as appears in Macro-blog link above) which is using a reference for the authenticationManager from the bean action method:

first, you need to expose the authenticationManager in the security context configuration file:

The code above is pretty clear, If fail (AuthenticationExcpetion thrown, show error message), else redirect to some URL.

The point here is some URL is critical, because if the user was trying to access resource "A", then spring security asked him to login first, then after login he should access resource "A" itself not a welcome screen.

This handled by spring security, but in our case, we need to ask Spring-security explicity to give us the "SavedURL" from the session. so the implmenetation of Util.getSavedUrl() is below:

Point #2 Handle HTTP error codes for Ajax requests:

Originally with regular HTTP requests (non-Ajax), when the user try to access a resource after session expired, spring security will send error code 302 to the browser, when browser sees the response code, he will do the redirect the Login page.

But in case of Ajax requests, the ajax client should handle this on his own.

In case of JSF, (I am not the JSF expert Guy :D ) JSF uses some internal protocol sending XML between the server and the client, and this XML is well defined in matter if the server wants the client to do redirect, the server doesn't send 302 for the client, instead, he sends a response like:

01 November 2014

The multi module project is folder with a parent pom file and some sub modules, each is a maven project reside in the directly of the parent project (also can reside in any relative path, not necessary to be in the parent folder).

And the parent project itself is a regular maven project but without src folder and with packaging `pom` instead of `jar` or `war`...

If you have a shared dependency, as if you work with spring framework, you can put the shared dependencies in the parent pom. and in sub modules pom you can put unique dependencies and also can have one module depend on others (web app module to depend on domain module and repository module)

The following is directory structure using parent module with two sub modules (quick-start and webapp)

22 October 2014

DB Transactions has 4 attributes, which is expressed as ACID, where:A -> Atomicity, means transaction run as an atomic single unit of work, either all is successes and committed or all rollbacked in case of failure.C -> Consistency, means the transactions should leave the DB data in consistent state, regardless of its success or fail. so, this attribute is ensured using the first attribute.I -> Isolation, means the user transaction should run in isolation from other users transaction, and no one should affected by others during the single transaction. also this ensures DB consistency.D -> Durable, means the transaction should be written permanent to the DB after the transaction committed, even if the system crashes afterwards.When two ore more transactions are operate concurrently on the same data, the following errors might happen:

The first transaction write some data to the DB but still the transaction not committed, a second transaction come and read the modified data, then the first transaction rolled-back.This called "Dirty reads", and can prevented by applying the "Isolation" attribute, so every transaction should be isolated from other transactions in terms on data modifications.

The first transaction read some data, then a second transaction come and modify that data and then commit, so the data written to the database. meanwhile the first transaction is still running and when come to read the same data again, it find it changed.This called "Non repeatable reads" which means multiple reads by some transaction to the same data is differ. and this can prevented by having some row-level locks on the database, so once a transaction start reading/modifying some data no other transaction cannot use until this transaction ends.

The first transaction read some rows using a certain where condition, then a second transaction come and insert a new row that reside in the where condition area and then committed. When the first transaction come and re-query the first select with that certain where condition, it finds the rows number changed.This called "Phantom reads" and this cab be prevented by applying table-level lock whenever a transaction come and start reading/modifying some data in a table, the transaction acquire full-table lock.

This leads to talk about Isolation levels, which are (from less control to more control, and more control means low performance):

Read UncommittedRead dirty data, data before being committed by other transactions, leads to all there "Dirty reads", "Non repeatable reads" and "Phantom reads"

Read CommittedRead only committed data, lead to only "Non repeatable reads" and "phantom reads".

Repeatable Read (lock data)Transaction acquire lock on the data being read (either cell-level or row-level locks), so nobody can change the data until transaction commit or rollback. but still "Phantom reads" can happen.

Serializable (lock table)Table-level lock. Nobody can touch the whole table until the transaction committed or rolled-back. no isolation violations can happen.